查找和替换一个给定的输入字符串,比如abc,并替换成另一个字符串,比如文件/tmp/file.txt中的XYZ,最简单的方法是什么?

我正在编写一个应用程序,并使用IronPython通过SSH执行命令-但我不太了解Unix,也不知道该寻找什么。

我听说Bash除了是一种命令行界面外,还可以是一种非常强大的脚本语言。所以,如果这是真的,我假设你可以执行这样的操作。

我可以用bash实现它吗?要实现我的目标,最简单的(一行)脚本是什么?


当前回答

我在其他帖子中发现了这个帖子,我认为它包含了最完整的答案,所以我也添加了我的答案:

sed and ed are so useful...by hand. Look at this code from @Johnny: sed -i -e 's/abc/XYZ/g' /tmp/file.txt When my restriction is to use it in a shell script, no variable can be used inside in place of "abc" or "XYZ". The BashFAQ seems to agree with what I understand at least. So, I can't use: x='abc' y='XYZ' sed -i -e 's/$x/$y/g' /tmp/file.txt #or, sed -i -e "s/$x/$y/g" /tmp/file.txt but, what can we do? As, @Johnny said use a while read... but, unfortunately that's not the end of the story. The following worked well with me: #edit user's virtual domain result= #if nullglob is set then, unset it temporarily is_nullglob=$( shopt -s | egrep -i '*nullglob' ) if [[ is_nullglob ]]; then shopt -u nullglob fi while IFS= read -r line; do line="${line//'<servername>'/$server}" line="${line//'<serveralias>'/$alias}" line="${line//'<user>'/$user}" line="${line//'<group>'/$group}" result="$result""$line"'\n' done < $tmp echo -e $result > $tmp #if nullglob was set then, re-enable it if [[ is_nullglob ]]; then shopt -s nullglob fi #move user's virtual domain to Apache 2 domain directory ...... As one can see if nullglob is set then, it behaves strangely when there is a string containing a * as in: <VirtualHost *:80> ServerName www.example.com which becomes <VirtualHost ServerName www.example.com there is no ending angle bracket and Apache2 can't even load. This kind of parsing should be slower than one-hit search and replace but, as you already saw, there are four variables for four different search patterns working out of one parse cycle.

在给定的假设下,我能想到的最合适的解决方案。

其他回答

你可以使用sed:

sed -i 's/abc/XYZ/gi' /tmp/file.txt

如果你不知道你的文件名,你可以使用find和sed:

find ./ -type f -exec sed -i 's/abc/XYZ/gi' {} \;

在所有Python文件中查找并替换:

find ./ -iname "*.py" -type f -exec sed -i 's/abc/XYZ/gi' {} \;

使用vim编辑器打开文件。命令模式

:%s/abc/xyz/g 

这是最简单的

当我被这个绊倒时,我很惊讶……

“mysql-server”包中有一个replace命令,如果你已经安装了它,请尝试一下:

# replace string abc to XYZ in files
replace "abc" "XYZ" -- file.txt file2.txt file3.txt

# or pipe an echo to replace
echo "abcdef" |replace "abc" "XYZ"

关于这一点,请参阅man replace。

我在其他帖子中发现了这个帖子,我认为它包含了最完整的答案,所以我也添加了我的答案:

sed and ed are so useful...by hand. Look at this code from @Johnny: sed -i -e 's/abc/XYZ/g' /tmp/file.txt When my restriction is to use it in a shell script, no variable can be used inside in place of "abc" or "XYZ". The BashFAQ seems to agree with what I understand at least. So, I can't use: x='abc' y='XYZ' sed -i -e 's/$x/$y/g' /tmp/file.txt #or, sed -i -e "s/$x/$y/g" /tmp/file.txt but, what can we do? As, @Johnny said use a while read... but, unfortunately that's not the end of the story. The following worked well with me: #edit user's virtual domain result= #if nullglob is set then, unset it temporarily is_nullglob=$( shopt -s | egrep -i '*nullglob' ) if [[ is_nullglob ]]; then shopt -u nullglob fi while IFS= read -r line; do line="${line//'<servername>'/$server}" line="${line//'<serveralias>'/$alias}" line="${line//'<user>'/$user}" line="${line//'<group>'/$group}" result="$result""$line"'\n' done < $tmp echo -e $result > $tmp #if nullglob was set then, re-enable it if [[ is_nullglob ]]; then shopt -s nullglob fi #move user's virtual domain to Apache 2 domain directory ...... As one can see if nullglob is set then, it behaves strangely when there is a string containing a * as in: <VirtualHost *:80> ServerName www.example.com which becomes <VirtualHost ServerName www.example.com there is no ending angle bracket and Apache2 can't even load. This kind of parsing should be slower than one-hit search and replace but, as you already saw, there are four variables for four different search patterns working out of one parse cycle.

在给定的假设下,我能想到的最合适的解决方案。

你也可以使用ed命令进行文件内搜索和替换:

# delete all lines matching foobar 
ed -s test.txt <<< $'g/foobar/d\nw' 

参见“使用ed通过脚本编辑文件”。