Answers:
最简单的方法是使用sed(或perl):
sed -i -e 's/abc/XYZ/g' /tmp/file.txt
由于该-i
选项,它将调用sed进行就地编辑。可以从bash调用它。
如果您真的只想使用bash,则可以使用以下方法:
while read a; do
echo ${a//abc/XYZ}
done < /tmp/file.txt > /tmp/file.txt.t
mv /tmp/file.txt{.t,}
这会遍历每一行,进行替换,然后写入一个临时文件(不想破坏输入内容)。最后的举动只是暂时地移动到原始名称。
sed
: s/..../..../ - Substitute
和 /g - Global
invalid command code C
错误的Mac用户请注意...对于就地替换,BSD sed
在-i
标志后需要文件扩展名,因为它会保存具有给定扩展名的备份文件。例如:sed -i '.bak' 's/find/replace/' /file.txt
您可以通过使用空字符串来跳过备份,如下所示:sed -i '' 's/find/replace/' /file.txt
s/abc/XYZ/gi
文件操纵通常不是由Bash完成,而是由Bash调用的程序来完成,例如:
perl -pi -e 's/abc/XYZ/g' /tmp/file.txt
该-i
标志告诉它执行就地替换。
请参阅参考资料,man perlrun
以获取更多详细信息,包括如何备份原始文件。
perl -pi -e 's/chdir (?:\\/[\\w\\.\\-]+)+/chdir blah/g' text
,但是在-e第1行中不赞成使用模式和后续单词之间没有空格的情况下,我始终会收到错误消息。 ?:\\ /在-e行1
当我偶然发现这一点时,我感到很惊讶。
软件包replace
附带有一个命令"mysql-server"
,因此如果已安装,请尝试一下:
# 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
更多信息,。
replace
是有用的独立工具,MySQL人员应单独发布并依赖它b)replace
需要一些MySQL o_O两种方式,安装mysql-server以获得替换将是错误的事情:)
mysql-server
软件包。正如@rayro所指出的,replace
它是其中的一部分。
与其他shell一样,Bash只是用于协调其他命令的工具。通常,您会尝试使用标准的UNIX命令,但是您当然可以使用Bash调用任何东西,包括您自己的编译程序,其他Shell脚本,Python和Perl脚本等。
在这种情况下,有两种方法可以做到这一点。
如果要读取文件,然后将其写入另一个文件,同时进行搜索/替换,请使用sed:
sed 's/abc/XYZ/g' <infile >outfile
如果您想就地编辑文件(就像在编辑器中打开文件,对其进行编辑然后保存一样),请向行编辑器“ ex”提供说明
echo "%s/abc/XYZ/g
w
q
" | ex file
Ex就像没有全屏模式的vi。您可以像在vi的':'提示符下输入相同的命令。
我在其他线程中找到了这个线程,我同意它包含了最完整的答案,所以我也添加了我的线程:
sed
而且ed
非常有用。从@Johnny看下面的代码:
sed -i -e 's/abc/XYZ/g' /tmp/file.txt
当我的限制是在shell脚本中使用它时,不能在其中使用任何变量来代替“ abc”或“ XYZ”。该BashFAQ似乎与我至少明白同意。因此,我不能使用:
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
但是,我们该怎么办?因为,@ Johnny说使用了一个,while read...
但不幸的是,这还不是故事的结局。以下与我很好地工作:
#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
......
可以看到是否nullglob
设置了then,当包含a的字符串包含*
in 时,它的行为很奇怪:
<VirtualHost *:80>
ServerName www.example.com
变成
<VirtualHost ServerName www.example.com
没有结束尖括号,Apache2甚至无法加载。
这种解析应该比一键搜索和替换要慢,但是,正如您已经看到的,对于四个不同的搜索模式,有四个变量在一个解析周期内起作用。
在给定的问题假设下,我能想到的最合适的解决方案。
sed -e "s/$x/$y/"
,它将起作用。不是双引号。如果变量中的字符串本身包含具有特殊含义的字符,可能会造成严重的混乱。例如,如果x =“ /”或x =“ \”。遇到这些问题时,这可能意味着您应该停止尝试使用Shell来完成这项工作。
您也可以使用该ed
命令进行文件内搜索和替换:
# delete all lines matching foobar
ed -s test.txt <<< $'g/foobar/d\nw'
请参见“ 使用脚本编辑文件ed
”中的更多内容。
sed -i <pattern> <filename>
)。非常好!
如果您正在处理的文件不是很大,并且暂时将其存储在变量中没问题,那么您可以一次在整个文件上使用Bash字符串替换-无需逐行进行遍历:
file_contents=$(</tmp/file.txt)
echo "${file_contents//abc/XYZ}" > /tmp/file.txt
整个文件的内容将被视为一个长字符串,包括换行符。
XYZ可以是一个变量,例如$replacement
,这里不使用sed的一个优点是您不必担心搜索或替换字符串可能包含sed模式定界符(通常但不一定是/)。缺点是无法使用正则表达式或sed的任何更复杂的操作。
如果将URL替换为“ /”字符,请小心。
有关如何执行此操作的示例:
sed -i "s%http://domain.com%http://www.domain.com/folder/%g" "test.txt"
摘自:http : //www.sysadmit.com/2015/07/linux-reemplazar-texto-en-archivos-con-sed.html
要非交互地编辑文件中的文本,您需要就地文本编辑器,例如vim。
这是如何从命令行使用它的简单示例:
vim -esnc '%s/foo/bar/g|:wq' file.txt
这几个 ex
实际的例子。
替换文字foo
与bar
文件中:
ex -s +%s/foo/bar/ge -cwq file.txt
删除多个文件的尾随空格:
ex +'bufdo!%s/\s\+$//e' -cxa *.txt
故障排除(端子卡住时):
-V1
参数以显示详细消息。-cwq!
。也可以看看:
-V1
,以强制退出,请使用wq!
。
您也可以在bash脚本中使用python。我在这里的一些最佳答案并没有取得太大的成功,并且发现它不需要循环就可以工作:
#!/bin/bash
python
filetosearch = '/home/ubuntu/ip_table.txt'
texttoreplace = 'tcp443'
texttoinsert = 'udp1194'
s = open(filetosearch).read()
s = s.replace(texttoreplace, texttoinsert)
f = open(filetosearch, 'w')
f.write(s)
f.close()
quit()