如何使用命令行在文本文件中查找和替换特定单词?

#1 楼

sed -i 's/original/new/g' file.txt


说明:



sed =流EDitor

-i =就地(即保存到原文件)

命令字符串:



s =替代命令

original =描述正则表达式替换的单词(或仅替换单词本身)

new =替换为

的文本g =全局(即替换所有单词,而不仅仅是第一次出现)


file.txt =文件名


评论


@Akiva如果在搜索sed中包含正则表达式特殊字符,则它们将匹配它们。如果要使用扩展RE,则添加-r标志。

–cscarney
2014年11月28日17:38



@mcExchange如果您具体需要匹配/字符,则可以使用其他字符作为分隔符(例如's_old / text_new / text_g')。否则,您可以在$ *之前放置\。 [\ ^获取文字字符。

–cscarney
15年8月12日在18:34



@BrianZ就文件系统而言,sed的输出是一个具有相同名称的新文件。它是通常报告的错误之一,不是错误

–cscarney
15-10-21在17:39



OSX命令sed -i'.bak''s / original / new / g'file.txt也可以使用零长度扩展名sed -i''s / original / new / g'file.txt运行,不会产生任何备份。

–柯克
16年6月6日在18:16

MacOS用户将必须在-i之后添加“”作为-i ed.gs/2016/01/26/os-x-sed-invalid-command-code的参数,以便覆盖该文件。

–geoyws
17年5月29日在9:44

#2 楼

有多种方法可以实现它。取决于人们尝试用字符串替换实现的复杂性,并取决于用户熟悉的工具,某些方法可能比其他方法更受青睐。

在此答案中,我使用的是简单的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感到好奇,那基本上是shell逐行读取文件的方式。请参阅此内容以供参考。

AWK

AWK是一种文本处理实用程序,非常适合此类任务。它可以根据正则表达式进行简单的替换,也可以进行更高级的替换。它提供两个功能:sub()gsub()。第一个仅替换第一个匹配项,而第二个-替换整个字符串中的匹配项。例如,如果我们有字符串one potato two potato,则将是以下结果: easy:

$ 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的版本,它可能有也可能没有就地编辑,因此通常的做法是保存并替换新文本。例如这样的东西:

awk '{sub(/blue/,"azure")}1' input.txt


SED

Sed是行编辑器。它还使用了正则表达式,但是对于简单的替换而言,它就足够了:

awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt


该工具的优点是它具有就地编辑功能,您可以启用它带有input.txt标志。

Perl

Perl是另一种经常用于文本处理的工具,但它是一种通用语言,用于网络,系统管理,桌面应用程序和许多其他地方。它从其他语言(例如C,sed,awk等)中借用了许多概念/功能。可以这样简单地替换:

sed 's/blue/azure/' input.txt


像sed一样,perl也带有-i标志。

Python

该语言用途广泛,还可以用于各种应用中。它具有很多用于处理字符串的功能,其中-i就是其中之一,因此,如果您拥有replace()之类的变量,则可以执行var="Hello World"

读取文件和替换字符串的简单方法就是:

perl -pe 's/blue/azure/' input.txt


但是,对于Python,您还需要输出到新文件,也可以在脚本本身中执行此操作。例如,这是一个简单的示例:

python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt


该脚本将以var.replace("Hello","Good Morning")作为命令行参数来调用。使用命令行参数运行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])




 $ ./myscript.py input.txt


当然,请确保input.txt位于当前工作目录中,并且首先,请确保将./myscript.py设置为可执行文件。

Python也可以具有正则表达式,尤其是chmod +x ./myscript.py模块,其中包含re功能,可用于更高级的替换。

评论


不错的编译!此处未提及的另一种可能方法是在unix中使用tr命令

–塔帕吉特·戴(Tapajit Dey)
19年4月8日在16:20



@TapajitDey是的,tr是另一个很好的工具,但是请注意,它是用于替换字符集的(例如,tr abc cde会将a转换为c,b转换为d。与用sed或python替换整个单词有点不同)

– Sergiy Kolodyazhnyy
19年4月8日在18:06

#3 楼

有很多不同的方法可以做到这一点。一种是使用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更有意义的方法是使用管道!

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


评论


注意猫文件中的猫| sed'...'是不必要的。您可以直接说sed'...'文件。

– fedorqui
2015年10月9日,11:54

的确可以进一步减少:sed -i'.bak'-e's / unicorn / fox / g; s / hyper / brown / g'yarly将按年采集文件,并在进行备份的同时进行2次更改。使用time bash -c“ $ COMMAND”计时,表明此版本快约5倍。

– pbhj
17-10-22在20:14

#4 楼

您可以在Ex模式下使用Vim:

 ex -s -c '%s/OLD/NEW/g|x' file
 



%选择所有行
s替换
g替换每行中的所有实例
x写(如果有)更改并退出


#5 楼

通过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",);}' file


仅在第一列上用0替换1。

通过Perl,
/>
$ echo 'foo' | perl -pe 's/foo/bar/g'
bar


#6 楼

sed是流编辑器,您可以使用|(管道)通过sed发送标准流(特别是STDIN和STDOUT),并以编程方式实时更改它们,使其成为Unix哲学传统中的便捷工具;但也可以使用下面提到的-i参数直接编辑文件。请考虑以下内容:

 sed -i -e 's/few/asd/g' hello.txt
 


s/用于将找到的表达式few替换为asd


勇敢的人。


勇敢的asd,勇敢的人。


/g代表“全局”,表示对整行都这样做。如果不使用/g(对于s/few/asd/,无论如何总是需要三个斜杠)并且few在同一行上出现两次,则只有第一个few更改为asd


几个男人,几个女人,勇敢。


asd男人,几个女人,勇敢。


在某些情况下,例如更改行首的特殊字符(例如,某些人用水平制表符代替大写的符号来引用电子邮件线程中的先前材料,而稍后在行中保留引用的代数不等式),但是在您的示例中,如果您指定在任何地方发生few都应将其替换,请确保已安装/g

以下两个选项(标志)组合为一个-ie

-i选项用于在文件hello.txt上进行原位编辑。

-e选项指示表达式/逗号要运行,在这种情况下为s/

注意:使用-i -e进行搜索/替换很重要。如果执行-ie,则会为每个文件创建备份,并附加字母“ e”。

#7 楼

您可以这样操作:

locate <part of filaname to locate> | xargs sed -i -e "s/<Old text>/<new text>/g" 


示例:
将所有出现的[logdir',''](不带[])替换为[logdir', os.getcwd()]在由locate命令生成的所有文件中,请执行:

ex1:

locate tensorboard/program.py | xargs sed -i -e "s/old_text/NewText/g"


ex2:

locate tensorboard/program.py | xargs sed -i -e "s/logdir', ''/logdir', os.getcwd()/g"


其中[tensorboard / program.py]是要搜索的文件

评论


你好您选择的字符串(logdir',``-> /logdir'、os.getcwd())使此答案难以解析。另外,值得指定您的答案首先找到要使用sed的文件,因为这不是问题的一部分。

–mwfearnley
18年8月22日在8:05

嗨,这个答案是搜索并替换所有文件,如果它在文件中找到

–NguyễnTuấnAnh
18年8月24日在2:11

我为他们在keras中使用tensorboard的所有人选择了这个答案,他们想将命令从以下位置更改:tensorboard --logdir ='/ path / to / log / folder /'使用:仅当保存在logs文件夹中时,才能使用tensorboard。这很方便

–NguyễnTuấnAnh
18年8月24日在2:27