我需要替换一个文件夹中的许多文件中的字符串,只有ssh访问服务器。我该怎么做呢?
当前回答
如果你有可以使用的文件列表
replace "old_string" "new_string" -- file_name1 file_name2 file_name3
如果你有所有可以使用的文件
replace "old_string" "new_string" -- *
如果你有文件扩展名列表,你可以使用
replace "old_string" "new_string" -- *.extension
其他回答
当使用-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 *可以工作。
multiedit命令脚本
multiedit [-n PATTERN] OLDSTRING NEWSTRING
根据Kaspar的回答,我编写了一个bash脚本来接受命令行参数,并有选择地限制与模式匹配的文件名。保存在$PATH中并使其可执行,然后使用上面的命令。
剧本如下:
#!/bin/bash
_help="\n
Replace OLDSTRING with NEWSTRING recursively starting from current directory\n
multiedit [-n PATTERN] OLDSTRING NEWSTRING\n
[-n PATTERN] option limits to filenames matching PATTERN\n
Note: backslash escape special characters\n
Note: enclose STRINGS with spaces in double quotes\n
Example to limit the edit to python files:\n
multiedit -n \*.py \"OLD STRING\" NEWSTRING\n"
# ensure correct number of arguments, otherwise display help...
if [ $# -lt 2 ] || [ $# -gt 4 ]; then echo -e $_help ; exit ; fi
if [ $1 == "-n" ]; then # if -n option is given:
# replace OLDSTRING with NEWSTRING recursively in files matching PATTERN
find ./ -type f -name "$2" -exec sed -i "s/$3/$4/g" {} \;
else
# replace OLDSTRING with NEWSTRING recursively in all files
find ./ -type f -exec sed -i "s/$1/$2/" {} \;
fi
有一个更简单的方法,使用一个简单的脚本文件:
# sudo chmod +x /bin/replace_string_files_present_dir
在gedit或你选择的编辑器中打开文件,我在这里使用gedit。
# sudo gedit /bin/replace_string_files_present_dir
然后在编辑器中将以下内容粘贴到文件中
#!/bin/bash
replace "oldstring" "newstring" -- *
replace "oldstring1" "newstring2" -- *
#add as many lines of replace as there are your strings to be replaced for
#example here i have two sets of strings to replace which are oldstring and
#oldstring1 so I use two replace lines.
保存文件,关闭gedit,然后退出您的终端,或者只是关闭它,然后启动它,以便能够加载您添加的新脚本。
导航到有多个要编辑的文件的目录。然后运行:
#replace_string_files_present_dir
按enter键,这将自动将包含它们的所有文件中的oldstring和oldstring1分别替换为正确的newstring和newstring1。
它将跳过不包含旧字符串的所有目录和文件。
如果您有多个目录的文件需要替换字符串,这可能有助于消除乏味的输入工作。你所要做的就是导航到这些目录,然后运行:
# replace_string_files_present_dir
你所要做的就是确保你已经包括或添加了所有替换字符串,就像我上面展示的那样:
替换 “oldstring” “newstring” -- *
在文件/bin/replace_string_files_present_dir的末尾。
要添加一个新的替换字符串,只需打开我们创建的脚本,在终端中输入以下命令:
Sudo gedit /bin/replace_string_files_present_dir
不要担心你添加的替换字符串的数量,如果没有找到oldstring,它们将没有任何影响。
我从另一篇文章中找到了这篇文章(不记得是哪篇了),虽然不是最优雅的,但它很简单,作为一个新手Linux用户,它没有给我带来任何麻烦
for i in *old_str* ; do mv -v "$i" "${i/\old_str/new_str}" ; done
如果有空格或其他特殊字符,请使用\
for i in *old_str\ * ; do mv -v "$i" "${i/\old_str\ /new_str}" ; done
对于子目录中的字符串使用**
for i in *\*old_str\ * ; do mv -v "$i" "${i/\old_str\ /new_str}" ; done
我给出了一个修复python源代码中常见shebang错误的示例。
您可以尝试grep/sed方法。下面是一个适用于GNU sed并且不会破坏git回购的程序:
$ grep -rli --exclude '*.git*' '#!/usr/bin/python' . | xargs -I {} \
gsed -i '' -e 's/#!\/usr\/bin\/python/#!\/usr\/bin\/env python/' {}
或者你可以使用greptile:)
$ greptile -x .py -l -i -g '#!/usr/bin/env python' -r '#!/usr/bin/python' .
我刚刚测试了第一个脚本,第二个脚本应该也可以工作。小心转义字符,我认为在大多数情况下使用greptile应该更容易。当然,您可以使用sed做许多有趣的事情,为此,最好与xargs一起使用sed。