从字符串中删除单词

时间:2017-02-27 03:07:55

标签: regex perl awk sed ksh

我想删除文件中的特定字词。

我们假设文件名A default document is not configured for the requested URL, and directory browsing is not enabled on the server. 包含以下字符串

agent_file.txt

我只想在这个文件中删除字符或单词-queues winall,dustat,envstat,netstat,iostat,winconfig,netwarestat,netwareconfig,pawmin,paw15,db2,sqlserver,vmstatvmw2,vmstatvm2,netstatvm,netstatvmw,vmstatvm,vmstatvmw,iostatvm,iostatvmw,envstatvm,envstatvmw,vmscpu,vmsdisk,vmsmem,vmstatvcw,process,winprocess ,所以我在Unix下使用下面的命令

process

输出

perl -pi -e 's/process//g' agent_file.txt

该字词已删除,但也会删除-queues winall,dustat,envstat,netstat,iostat,winconfig,netwarestat,netwareconfig,pawmin,paw15,db2,sqlserver,vmstatvmw2,vmstatvm2,netstatvm,netstatvmw,vmstatvm,vmstatvmw,iostatvm,iostatvmw,envstatvm,envstatvmw,vmscpu,vmsdisk,vmsmem,vmstatvcw,,win 的部分内容。

如果只有winprocess以及之前的逗号process,我该如何删除?

输出应为

,

6 个答案:

答案 0 :(得分:1)

使用逗号(-a)自动拆分(-F,),以完全避免逗号问题

perl -F, -lane 'print join ",", grep { not /^process$/ } @F' input  > output

输入被,分解为@Fgrep过滤掉了该字词,其余字段由,

加入

为了更改输入文件,请添加-i并删除> output

请参阅Command switches in perlrun

问题在于,第一个和最后一个单词有一个逗号,如果删除它们需要删除,而其他单词有两个逗号,需要留下。正则表达式的一种方法是进行两次传递,删除单词然后使用额外的逗号(仍然要小心第一个和最后一个)。

或者在替换部件中运行代码以适当选择案例

echo "go,stay,ago,go,got,end,go" | 

    perl -pe's/(,)?\bgo\b(,)?/$1 && $2 && ","/ge'

打印:stay,ago,got,end/e将替换方评估为Perl代码。

如果两个逗号都在那里($1 && $2),那么(&&)我们会用逗号(",")替换。

这很有效,因为在Perl && returns the value

  

||//&&运算符返回最后评估的值(与C' s ||&&不同,返回0或1)。

答案 1 :(得分:1)

这是一个awk解决方案。

awk 'BEGIN{OFS=FS=","} {for(i=1;i<=NF;i++) if($i=="process") $i=""} 1' file

这会将输入和输出的字段分隔符设置为逗号,然后逐步执行字段,检查您感兴趣的字符串的等效性,如果匹配则清空字段。最后的1是&#34;打印当前行&#34;。

同样,人们可以按记录而不是字段来切片输入数据:

awk 'BEGIN{ORS=RS=","} /^process$/{next} 1' file

awk 'BEGIN{ORS=RS=","} $0=="process"{next} 1' file

它使用逗号作为RECORD分隔符(RS)遍历您的输入,以便可以使用awk的记录感知来评估单个单词。您可以通过正则表达式进行评估 - 正则表达式稍慢,但似乎可以节省两个字符的输入。 : - )

使用RS / ORS的策略消除了您注意到的字段被清空但未被删除的问题。当逗号是记录分隔符时,跳过的记录会导致记录分隔符不被显示,这更接近于#34;理想的&#34;输出你已经包含在你的问题中了。

最后一个选项可能是在shell(ksh)中执行此操作。这将具有最大的可移植性(你不必担心perl版本,awk / sed是GNU还是BSD还是其他东西)。缺点是使用下面的方法,您的文件大小将受到系统内存(可能是可配置的限制)的限制。

$ IFS=, read -A arr < file
$ for i in "${!arr[@]}"; do [[ "${arr[$i]}" == "process" ]] && unset arr[$i]; done
$ output=$(printf "%s," "${arr[@]}")
$ echo "${output%,}"
-queues winall,dustat,envstat,netstat,iostat,winconfig,netwarestat,netwareconfig,pawmin,paw15,db2,sqlserver,vmstatvmw2,vmstatvm2,netstatvm,netstatvmw,vmstatvm,vmstatvmw,iostatvm,iostatvmw,envstatvm,envstatvmw,vmscpu,vmsdisk,vmsmem,vmstatvcw,winprocess

请注意,只有$output变量才能删除由printf生成的尾随逗号。另一种选择可能是全局设置$IFS

$ IFS=,
$ echo "${arr[*]}"
-queues winall,dustat,envstat,netstat,iostat,winconfig,netwarestat,netwareconfig,pawmin,paw15,db2,sqlserver,vmstatvmw2,vmstatvm2,netstatvm,netstatvmw,vmstatvm,vmstatvmw,iostatvm,iostatvmw,envstatvm,envstatvmw,vmscpu,vmsdisk,vmsmem,vmstatvcw,winprocess

我应该指出,尽管有外观,printf选项并没有真正产生外部命令,因为ksh将printf实现为内置命令。

答案 2 :(得分:0)

你可以分三步完成

sed 's/,process,/,/g;s/^process,//;s/,process$//'   

测试位置,:中间,开始或结束。

答案 3 :(得分:0)

如果以逗号分隔,请将它们用于制作单词。

perl -pi -e "s/, \s* process\s* , /, /g filename 

如果在逗号之后或之前没有空格,则删除\ s *

答案 4 :(得分:0)

或许这样吗?

它会搜索process的所有匹配项,使用单词边界确保它不会作为另一个单词的一部分找到,并且还会在之前和之后匹配可选的逗号,。如果找到两个逗号(在列表中间找到process),则匹配将替换为单个逗号;如果只有一个逗号,则将其删除(process仅出现在开头或结尾处列表)

perl -pi -e 's/ ,? \b process \b ,? ) / $1 =~ tr/,// > 1 ? ',' : '' /xge' agent_file.txt

答案 5 :(得分:0)

awk '{sub(/process,/,"")}1' file