使用命令查找和替换文件中的文本
如何使用命令行查找和替换文本文件中的特定单词?
sed -i 's/original/new/g' file.txt
说明:
-
sed
= Stream EDitor -
-i
=就地(即保存回原始文件) -
命令字符串:
-
s
=替代命令 -
original
=描述要替换的单词的正则表达式(或只是单词本身) -
new
=要替换它的文本 -
g
=全局(即替换所有而不仅仅是第一次出现)
-
-
file.txt
=文件名
有许多不同的方法可以做到这一点。 一个是使用sed
和Regex。 SED是用于过滤和转换文本的流编辑器。 一个例子如下:
marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orly marco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarly marco@imacs-suck: ~$ cat yarly The quick brown unicorn jumped over the hyper sleeping dog
另一种可能比< strin
和> strout
更有意义的> strout
是使用管道!
marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowai marco@imacs-suck: ~$ cat nowai The quick brown fox jumped over the lazy sleeping dog
通过awk的gsub命令,
awk '{gsub(/pattern/,"replacement")}' file
例:
awk '{gsub(/1/,"0");}' file
在上面的例子中,所有的1都被0代替,而不管它所在的列。
如果您想在特定列上进行替换,请执行以下操作,
awk '{gsub(/pattern/,"replacement",column_number)}' file
例:
awk '{gsub(/1/,"0",$1);}' file
它仅在第1列中将0替换为0。
通过Perl,
$ echo 'foo' | perl -pe 's/foo/bar/g' bar
您可以在Ex模式下使用Vim:
ex -sc '%s/OLD/NEW/g|x' file
-
%
选择所有行 -
替代品
-
g
替换每行中的所有实例 -
如果已经进行了更改(他们有),则写入并退出
有很多方法可以实现它。 根据用字符串替换尝试实现的复杂性,并且取决于用户熟悉的工具,某些方法可能比其他方法更受欢迎。
在这个答案中,我使用简单的input.txt
文件,您可以使用它来测试此处提供的所有示例。 文件内容:
roses are red , violets are blue This is an input.txt and this doesn't rhyme
BASH
Bash并不是真正意义上的文本处理,但简单的替换可以通过参数扩展来完成,特别是在这里我们可以使用简单的结构${parameter/old_string/new_string}
。
#!/bin/bash while IFS= read -r line do case "$line" in *blue*) printf "%s\n" "${line/blue/azure}" ;; *) printf "%s\n" "$line" ;; esac done < input.txt
这个小脚本不进行就地替换,这意味着您必须将新文本保存到新文件中,并删除旧文件,或者mv new.txt old.txt
旁注:如果你对while IFS= read -r ; do ... done < input.txt
原因感到好奇while IFS= read -r ; do ... done < input.txt
while IFS= read -r ; do ... done < input.txt
使用,它基本上是shell逐行读取文件的方式。 请参阅此参考。
AWK
作为文本处理实用程序的AWK非常适合此类任务。 它可以基于正则表达式进行简单替换和更高级的替换。 它提供了两个函数: sub()
和gsub()
。 第一个只替换第一个匹配项,而第二个替换整个字符串中的匹配项。 例如,如果我们有one potato two potato
串,这将是结果:
$ echo "one potato two potato" | awk '{gsub(/potato/,"banana")}1' one banana two banana $ echo "one potato two potato" | awk '{sub(/potato/,"banana")}1' one banana two potato
AWK可以将输入文件作为参数,因此使用input.txt
执行相同操作很容易:
awk '{sub(/blue/,"azure")}1' input.txt
根据您拥有的AWK版本,它可能有也可能没有就地编辑,因此通常的做法是保存和替换新文本。 例如这样的事情:
awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt
SED
Sed是一个行编辑器。 它也使用正则表达式,但对于简单的替换,它足以做:
sed 's/blue/azure/' input.txt
这个工具的优点是它具有就地编辑function,您可以使用-i
标志启用它。
Perl的
Perl是另一种经常用于文本处理的工具,但它是一种通用语言,用于网络,系统管理,桌面应用程序和许多其他地方。 它借用了其他语言的许多概念/特性,如C,sed,awk和其他语言。 简单替换可以这样做:
perl -pe 's/blue/azure/' input.txt
像sed一样,perl也有-i标志。
python
这种语言非常通用,也可用于各种应用。 它有许多用于处理字符串的函数,其中有replace()
,所以如果你有变量如var="Hello World"
,你可以做var.replace("Hello","Good Morning")
读取文件和替换字符串的简单方法如下:
python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt
但是,使用Python,您还需要输出到新文件,您也可以在脚本本身中执行此操作。 例如,这是一个简单的:
#!/usr/bin/env python import sys import os import tempfile tmp=tempfile.mkstemp() with open(sys.argv[1]) as fd1, open(tmp[1],'w') as fd2: for line in fd1: line = line.replace('blue','azure') fd2.write(line) os.rename(tmp[1],sys.argv[1])
使用input.txt
作为命令行参数调用此脚本。
Python也可以有正则表达式,特别是有re
模块,它有re.sub()
函数,可以用于更高级的替换。
sed
是s tream ed itor ,因为你可以使用|
(管道)通过sed
发送标准流 (特定于STDIN和STDOUT)并在运行时以编程方式更改它们,使其成为Unix哲学传统中的一个方便工具; 但也可以使用下面提到的-i
参数直接编辑文件。
请考虑以下事项 :
sed -i -e 's/few/asd/g' hello.txt
s/
用于使用asd
来表示找到的表达式:
少数,勇敢。
asd,勇敢。
/g
代表“全局”,意思是为整行执行此操作。 如果你不使用/g
(使用s/few/asd/
,无论如何总是需要三个斜杠),并且few
在同一行上出现两次,只有前few
更改为asd
:
少数男人,少数女人,勇敢者。
asd男人,少数女人,勇敢。
这在某些情况下非常有用,例如在行的开头更改特殊字符(例如,替换某些人用于引用电子邮件线程中具有水平制表符的先前材料的大于符号,同时在行中留下引用的代数不等式未触动过),但是在你的例子中你指定了few
发生的事情,它应该被替换,确保你有/g
。
以下两个选项(标志)合并为一个, -ie
:
-i
选项用于编辑文件hello.txt
。
-e
选项表示要运行的e xpression /命令,在本例中为s/
。
注意:使用-i -e
进行搜索/替换非常重要。 如果您执行-ie
,则会为每个附加字母“e”的文件创建备份。
你可以这样做:
locate | xargs sed -i -e "s///g"
示例:在所有由locate命令生成的文件中用[logdir’,os.getcwd()]替换所有出现的[logdir’,”](不带[]),执行:
locate tensorboard/program.py | xargs sed -i -e "s/logdir', ''/logdir', os.getcwd()/g"
其中[tensorboard / program.py]是要搜索的文件