Regex 从字符串中删除单词

Regex 从字符串中删除单词,regex,perl,awk,sed,ksh,Regex,Perl,Awk,Sed,Ksh,我想从文件中删除一个特定的单词 假设文件名agent\u file.txt包含以下字符串 -queues winall,dustat,envstat,netstat,iostat,winconfig,netwarestat,netwareconfig,pawmin,paw15,db2,sqlserver,vmstatvmw2,vmstatvm2,netstatvm,netstatvmw,vmstatvm,vmstatvmw,iostatvm,iostatvmw,envstatvm,envstat

我想从文件中删除一个特定的单词

假设文件名
agent\u 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
我只想删除这个文件中的字符或单词
process
,所以我在Unix下使用下面的命令

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
的一部分

如何仅删除
进程
以及前面的逗号
(如果有)

输出应该是

-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

你可以分三步来做

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

位置测试:介于中间、开始或结束。

您可以分三步进行

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

测试位置:在中间、开头或结尾。

如果是逗号分隔的,请使用它们使其成为一个单词

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

如果逗号后面或前面没有空格,请删除\s*

如果是逗号分隔的,请将其用作单词

perl -pi -e "s/, \s* process\s* , /, /g filename 
如果逗号之后或之前没有空格,则删除\s*

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

perl -F, -lane 'print join ",", grep { not /^process$/ } @F' input  > output
输入被
分解成
@F
grep
过滤掉这个词,其余的词通过

要在适当位置更改输入文件,请添加
-i
并删除
>输出


问题是,第一个和最后一个单词有一个逗号,如果它们被删除,需要去掉,而其他单词有两个逗号,其中一个需要保留。使用正则表达式的一种方法是进行两次传递,删除单词,然后添加逗号(仍然要注意第一个和最后一个)

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

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

    perl -pe's/(,)?\bgo\b(,)?/$1 && $2 && ","/ge'
打印:
stay、ago、got、end
。将替换端作为Perl代码进行计算

如果两个逗号都存在(
$1&&$2
),则(
&&
)将替换为逗号(
“,”

这是因为在Perl中

||
/
&
运算符返回最后计算的值(不同于C的
|
&
运算符返回0或1)

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

perl -F, -lane 'print join ",", grep { not /^process$/ } @F' input  > output
输入被
分解成
@F
grep
过滤掉这个词,其余的词通过

要在适当位置更改输入文件,请添加
-i
并删除
>输出


问题是,第一个和最后一个单词有一个逗号,如果它们被删除,需要去掉,而其他单词有两个逗号,其中一个需要保留。使用正则表达式的一种方法是进行两次传递,删除单词,然后添加逗号(仍然要注意第一个和最后一个)

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

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

    perl -pe's/(,)?\bgo\b(,)?/$1 && $2 && ","/ge'
打印:
stay、ago、got、end
。将替换端作为Perl代码进行计算

如果两个逗号都存在(
$1&&$2
),则(
&&
)将替换为逗号(
“,”

这是因为在Perl中

||
/
&
运算符返回最后计算的值(不同于C的
|
&
运算符返回0或1)


这里有一个
awk
解决方案

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

这将使用逗号作为记录分隔符(RS)遍历您的输入,以便使用awk的记录感知来评估单个单词。您可以通过正则表达式进行计算,也可以不通过正则表达式进行计算——正则表达式的速度稍微慢一点,但似乎可以为您节省两个键入字符。:-)

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


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


我应该指出,尽管出现了
printf
选项,但它并没有真正生成外部命令,因为ksh将
printf
作为一个内置实现。

这里有一个
awk
解决方案

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

这将使用逗号作为记录分隔符(RS)遍历您的输入,以便使用awk的记录感知来评估单个单词。您可以通过正则表达式进行计算,也可以不通过正则表达式进行计算——正则表达式的速度稍微慢一点,但似乎可以为您节省两个键入字符。:-)

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


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

我应该指出,尽管出现了
printf
选项,但它并没有真正生成外部命令,因为ksh将
printf
作为一个内置命令来实现。

可能是这样的吗

它搜索所有出现的
过程
,使用单词边界确保它不作为另一个单词的一部分被找到,并且还匹配可选逗号
前后。匹配项被单个c替换
awk '{sub(/process,/,"")}1' file