我需要替换一个文件夹中的许多文件中的字符串,只有ssh访问服务器。我该怎么做呢?


当前回答

当使用-i开关调用时,流编辑器确实会“inplace”修改多个文件,该开关以备份文件结尾作为参数。所以

sed -i.bak 's/foo/bar/g' *

在此文件夹中的所有文件中,将foo替换为bar,但不会下降到子文件夹中。但是,这将为目录中的每个文件生成一个新的.bak文件。 要递归地为该目录及其所有子目录中的所有文件执行此操作,您需要一个助手(如find)来遍历目录树。

find ./ -print0 | xargs -0 sed -i.bak 's/foo/bar/g' *

Find允许您进一步限制要修改的文件,通过指定进一步的参数,如Find ./ -name '*.php' -或name '*.html' -print0(如有必要)。


注意:GNU sed不需要文件结尾,sed -i 's/foo/bar/g' *也可以;FreeBSD sed要求扩展,但允许中间有一个空格,因此sed -i .bak s/foo/bar/g *可以工作。

其他回答

在MacBook Pro上,我使用了以下方法(灵感来自https://stackoverflow.com/a/19457213/6169225):)

sed -i '' -e 's/<STR_TO_REPLACE>/<REPLACEMENT_STR>/g' *

-i "将确保您没有备份。 -e表示现代正则表达式。

下面的命令可以用来首先搜索文件和替换文件:

find . | xargs grep 'search string' | sed 's/search string/new string/g'

例如

find . | xargs grep abc | sed 's/abc/xyz/g'

我对许多答案的问题是,我需要替换许多文件中的文件路径。虽然有一个答案提到了这一点,但对我来说并不管用。我的解决方案:

首先,生成一个要更改的文件名列表。

filelist=($(find /path/to/your/folder | xargs grep '/path/to/fix' | cut -d : -f 1 | tr '\n' ' '))

上面的命令所做的是,管道到grep的find生成包含/路径/到/fix的文件名。然而,grep也打印出字符串所在的行,所以cut命令去掉了这个,只保留文件名。Tr将换行符替换为空格,允许将文件列表存储为数组。

for file in "${filelist[@]}"; do sed -i.bak 's+/path/to/fix+/new/path/for/my/file+g' $file; done

这个sed命令利用了这个问题的其他答案,并使用+作为分隔符而不是普通的/,因为文件路径中使用了/字符。

要替换多个文件中的字符串,您可以使用:

grep -rl string1 somedir/ | xargs sed -i 's/string1/string2/g'

E.g.

grep -rl 'windows' ./ | xargs sed -i 's/windows/linux/g'

源的博客

第一行出现的“foo”将被替换为“bar”。你可以用第二行来检查。

grep -rl 'foo' . | xargs sed -i 's/foo/bar/g'
grep 'foo' -r * | awk -F: {'print $1'} | sort -n | uniq -c