【问题标题】:Delete lines which maching certain criteria删除符合特定条件的行
【发布时间】:2019-06-21 02:58:51
【问题描述】:

有多个输入文件(eg: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

【问题讨论】:

  • 请提供更多详细信息、示例输入、预期输出等。请阅读how-to-askmcve
  • 我现在已经编辑了帖子。希望现在很清楚
  • 对我来说,您似乎想要一个完整的解决方案并且没有表现出任何努力。你试过什么?您当前的代码是什么,该代码中什么不起作用?
  • 选择代码,点击编辑器上的{}按钮,不要使用双换行符,这会使帖子难以阅读。
  • 编辑帖子使其可读...

标签: linux awk sed grep


【解决方案1】:

猜你想要这样的东西:

$ 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

【讨论】:

  • 你的文字匹配部分没问题。但是删除不匹配的行并不清楚。如何使用 -i 就地? (我有 GNU Awk 3.1.8)
  • 定义clear。我正在为您提供解决方案,而不是提供您的逐行教程。你有责任明确提出问题,而不是我的回答。 3.1.8 不支持,改为其他方式。 @user2650100
  • 感谢您的支持。但我不知道如何在上面的 awk 命令中使用 -i 选项。 (抱歉,我以前没有这方面的经验) awk -F, '!($2=="WoW" && ($5~"^M_(SILVER|GOLD) *$"))' file1
  • @user2650100 更新您的awk 版本,或使用临时文件并在之后重命名。
  • 我已经升级了 Awk 版本 GNU Awk 4.1.3,因为我有 100 多个文件,创建临时文件并重命名它是不切实际的。
【解决方案2】:

通常一个 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的可能性。使用它来cat文件,在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. 您在 sed 上复制/粘贴部分代码而不了解您所做的或阅读的内容,这有点危险。对于在这部分行之前已经完成的目的,这部分代码不需要(并且无用)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    相关资源
    最近更新 更多