删除符合特定条件的行

时间:2019-01-28 06:08:08

标签: linux awk sed grep

有多个输入文件(例如:file1,file2,file3 ....),每个文件包含如下几行。

文件1:

123,WoW,45,2018,M_SILVER    
124,WoW_HD,2018,M_SILVER    
125,WoW,45,2018,M_SILVER_FTTH    
126,WoW,45,2018,M_GOLD

文件2:

133,WoW,45,2019,M_SILVER    
134,WoW_HD,2019,M_SILVER    
135,WoW,45,2019,M_SILVER_FTTH    
136,WoW,45,2019,M_GOLD 

我需要删除包含WoW的行,并且(M_SILVER或M_GOLD)输出应仅包含以下行。

文件1:

124,WoW_HD,2018,M_SILVER    
125,WoW,45,2018,M_SILVER_FTTH 

文件2:

134,WoW_HD,2019,M_SILVER    
135,WoW,45,2019,M_SILVER_FTTH 

文件名无法更改。 希望现在问题很清楚,你们可以提供解决方案。

尝试如下所示:

ls | grep file| sort | while read line ; do cat $line | grep WoW |grep -v WoW_HD | grep 'M_SILVER\|M_GOLD' | sed -i '/$line/d' ./infile;done

2 个答案:

答案 0 :(得分:0)

猜你想要这样的东西:

$ awk -F, '!($2=="WoW" && ($5~"^M_(SILVER|GOLD) *$"))' file1
124,WoW_HD,2018,M_SILVER
125,WoW,45,2018,M_SILVER_FTTH

$ awk -F, '!($2=="WoW" && ($5~"^M_(SILVER|GOLD) *$"))' file2
134,WoW_HD,2019,M_SILVER
135,WoW,45,2019,M_SILVER_FTTH

如果您使用的是GNU awk 4.1.0+,则可以添加-i inplace开关来替换文件。
file1 / file2更改为file*或其他名称以匹配多个文件。
还是像您之前所做的那样,ls并馈送到xargs,然后通过管道传递到awk

答案 1 :(得分:0)

sed或grep通常就足够了

sed -i -e '/,Wow,.*,M_SILVER$/d;/,Wow,.*,M_GOLD$/d' file[1-9]*

评论您的行:

ls | grep file| sort | while read line ; do cat $line | grep WoW |grep -v WoW_HD | grep 'M_SILVER\|M_GOLD' | sed -i '/$line/d' ./infile;done


ls | grep file| sort | while read line ; do cat $line ... ;done

这里不需要这样做,ls *file*就足够了,您不需要排序,可以直接使用ls可能性。用它来整理文件,然后在for循环中与直接制作文件一起使用     用于文件中的文件*;做...;完成

cat $line | grep WoW |grep -v WoW_HD | grep 'M_SILVER\|M_GOLD' |

grep可以一行完成所有这些操作(使用您的数据格式)。     grep -v',哇,。*,(M_SILVER \ | M_GOLD)'$ File> NewFile

| sed -i '/$line/d' ./infile

这将要求sed从文件./infile中进行修改,以“选择行末尾带有单词line的模式的行并删除它,其他保持不变”。     如果您在sed上复制/粘贴部分代码,却不了解您的操作或未读到它,这很危险。出于这一行之前已经完成的目的,不需要(也没有用)这部分代码。