从Bash命令查找并replace文本文件

find并replace给定的inputstring(比如abc ,并replace为另一个string(比如文件/tmp/file.txt XYZ ,最简单的方法是什么?

我正在写一个应用程序,并使用IronPython通过SSH执行命令 – 但我不知道Unix那么好,不知道该找什么。

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

我可以用bash来做到这一点吗?为了实现我的目标,最简单的(一行)脚本是什么?

最简单的方法是使用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,}

这在每一行循环,做一个replace,并写入一个临时文件(不想打破input)。 最后的举动只是暂时的移动到原来的名字。

文件操作通常不是由Bash完成的,而是由Bash调用的程序完成的,例如:

 > perl -pi -e 's/abc/XYZ/g' /tmp/file.txt 

-i标志告诉它做一个就地replace。

有关更多详细信息,请参阅man perlrun ,其中包括如何备份原始文件。

我很惊讶,因为我偶然发现了这个…

有一个与“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" 

看到更多的在这个…

像其他shell一样,Bash只是一个协调其他命令的工具。 通常你会尝试使用标准的UNIX命令,但你当然可以使用Bash调用任何东西,包括你自己编译的程序,其他shell脚本,Python和Perl脚本等。

在这种情况下,有几种方法可以做到这一点。

如果您想要读取文件并将其写入另一个文件,请按照要求进行search/replace,请使用sed:

 sed 's/abc/XYZ/g' <infile >outfile 

如果要编辑文件(就像在编辑器中打开文件,编辑文件,然后保存文件一样),向线编辑器提供指令“ex”

 echo "%s/abc/XYZ/g w q " | ex file 

Ex就像没有全屏模式的vi。 你可以在vi的':'提示符下input相同的命令。

find这个线程之中,我同意它包含最完整的答案,所以我也加我的:

1)sed和ed是如此有用…手! 从@Johnny看这个代码:

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

2)当我的限制是通过shell脚本使用它,然后,没有variables可以在内部使用abc或XYZ! 这似乎同意我的理解,至less。 所以,我不能使用:

 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 ...... 

3)可以看到是否设置了nullglob,那么当存在一个包含*的string

 <VirtualHost *:80> ServerName www.example.com 

成为

 <VirtualHost ServerName www.example.com 

没有结束的angular度支架,Apache2甚至无法加载!

4)这种parsing应该比单击search和replace要慢,但是正如你已经看到的那样,在一个parsing周期内,4个不同的search模式有4个variables!

我可以用给定的问题假设来思考最合适的解决scheme。

这是一个旧的post,但任何人想要使用variables作为@centurian说,单引号意味着什么都不会扩大。

一个简单的方法来获取variables是做string连接,因为这是通过并置在bash中完成的,以下应该工作:

sed -i -e 's/'"$var1"'/'"$var2"'/g' /tmp/file.txt

您也可以使用ed命令进行文件内search并replace:

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

有关bash-hacker网站的更多信息,

你可以使用sed

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

如果您不确定要查找的文本是abc或ABC还是AbC,请使用我作为忽略大小写…

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

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

查找并replace所有的python文件:

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

如果用“/”字符replaceurl,请小心。

如何做到这一点的一个例子:

 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编辑器的@slim答案 ,它基本上是一样的东西。

这里有几个实际的例子。

在文件中用barreplace文本foo

 ex -s +%s/foo/bar/ge -cwq file.txt 

删除多个文件的尾部空格:

 ex +'bufdo!%s/\s\+$//e' -cxa *.txt 

也可以看看:

  • 如何非交互式地编辑文件(例如在pipe道中)? 在Vi SE

find./ -type f -name“file * .txt”| xargs sed -i -e's / abc / xyz / g'

你可以使用rpl命令。 比如你想在整个php项目中改变域名。

 rpl -ivRpd -x'.php' 'old.domain.name' 'new.domain.name' ./path_to_your_project_folder/ 

这不是原因,但它是一个非常快速和有用的。 🙂

你也可以在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() 

如果你正在处理的文件不是那么大,并且暂时将其存储在一个variables中是没有问题的,那么你可以在整个文件中一次使用Bashstringreplace – 没有必要一条一条地检查它:

 file_contents=$(</tmp/file.txt) echo "${file_contents//abc/XYZ}" > /tmp/file.txt 

整个文件内容将被视为一个长string,包括换行符。

XYZ可以是一个variables,例如$replacement ,在这里不使用sed的一个好处是你不必担心search或replacestring可能包含sed模式分隔符(通常但不一定是/)。 缺点是不能使用正则expression式或任何sed的更复杂的操作。