我想删除文件中的特定字词。
我们假设文件名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
,我该如何删除?
输出应为
,
答案 0 :(得分:1)
使用逗号(-a
)自动拆分(-F,
),以完全避免逗号问题
perl -F, -lane 'print join ",", grep { not /^process$/ } @F' input > output
输入被,
分解为@F
。 grep
过滤掉了该字词,其余字段由,
为了更改输入文件,请添加-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