2014-10-28 19 views
0

我需要在管道分隔文件中搜索特定文本并删除与文本匹配的列。当文本与搜索字符串匹配时删除管道分隔文件中的列

例如: 我的文件

1|2|test123|3|4|5....|n 
6|7|5|test123|10|11.....|n 
6|7|1|9|test123|11.....|n 

需要搜索包含 “测试” 列,删除列

新的文件应该是这样

1|2|3|4|5....|n 
6|7|5|10|11.....|n 
6|7|1|9|11.....|n 

我已经试过

awk 'BEGIN{FS=OFS="|"}{$2=$3="";gsub(/[|]+/,"|")}1' test.txt >> test5.txt 

命令其中列号是显式硬编码的,但需要脚本来搜索文本然后删除列。

回答

0

所有的例子都使用数据文件:

1|2|test123|3|4|5....|n 
6|7|5|test123|10|11.....|n 
6|7|1|9|test123|11.....|n 
test|1|2|3|4|5......|n 
1|2|3|4|5|6.....|n-test-n 
1|2|test|and-test-again|3|4|5|6.....|n-test-n 

至少有两种方法可以解决这个。一个是纯文本:替换的序列管,零个或多个非管,单词“测试”,零个或多个非管道,和另一个管与单个管:

awk '{ gsub(/\|[^|]*test[^|]*\|/, "|"); print }' test.txt >> test5.txt 

输出:

1|2|3|4|5....|n 
6|7|5|10|11.....|n 
6|7|1|9|11.....|n 
test|1|2|3|4|5......|n 
1|2|3|4|5|6.....|n-test-n 
1|2|and-test-again|3|4|5|6.....|n-test-n 

鉴于字“测试”可以在第一或最后一列出现,你必须更加努力地工作,以对付那些:

awk '{ gsub(/\|[^|]*test[^|]*\|/, "|"); # Middle 
     gsub(/^[^|]*test[^|]*\|/, ""); # Start 
     gsub(/\|[^|]*test[^|]*$/, ""); # End 
     print }' test.txt >> test5.txt 

输出:

1|2|3|4|5....|n 
6|7|5|10|11.....|n 
6|7|1|9|11.....|n 
1|2|3|4|5......|n 
1|2|3|4|5|6..... 
1|2|and-test-again|3|4|5|6..... 

并且假设test可以出现在相邻的字段中,则必须对“中间”模式进行两次扫描。

awk '{ gsub(/\|[^|]*test[^|]*\|/, "|"); # Middle - 1 
     gsub(/\|[^|]*test[^|]*\|/, "|"); # Middle - 2 
     gsub(/^[^|]*test[^|]*\|/, ""); # Start 
     gsub(/\|[^|]*test[^|]*$/, ""); # End 
     print }' test.txt >> test5.txt 

输出:

1|2|3|4|5....|n 
6|7|5|10|11.....|n 
6|7|1|9|11.....|n 
1|2|3|4|5......|n 
1|2|3|4|5|6..... 
1|2|3|4|5|6..... 

通过每一行的字段的另一种方法的扫描,不打印那些包含“测试”。

awk -F '|' \ 
    '{ pad = ""; 
     for (i = 1; i <= NF; i++) 
     { 
     if ($i !~ /test/) 
     { 
      printf("%s%s", pad, $i); 
      pad = "|"; 
     } 
     } 
     print ""; 
    }' test.txt >> test5.txt 

输出:

1|2|3|4|5....|n 
6|7|5|10|11.....|n 
6|7|1|9|11.....|n 
1|2|3|4|5......|n 
1|2|3|4|5|6..... 
1|2|3|4|5|6..... 
+0

的awk -F '|' \ '{pad =“”; (i = 1; i <= NF; i ++) if($ i!〜/ test /) printf(“%s%s”,pad,$ i); pad =“|”; } } print“”; }'在这段代码中,我在哪里传递I/P文件名? – elvisthom 2014-10-28 07:19:29

+0

剧本结束后,在单引号结尾之后。你有'awk

0

file.txt的

1|2|test123|3|4|5....|n 
6|7|5|test123|10|11.....|n 
6|7|1|9|test123|11.....|n 

脚本:

sed 's/test123|//' file.txt >> file1.txt 
+0

Nit picking:仅删除包含'test123'的列而不是'test';当'test123'(或'test')不在字段的末尾时,它们不会删除它们;当字段中除'test123'(或'test')之外还有其他字符时,不会删除整个字段;不会将其从行上的最后一个字段中删除。 – 2014-10-28 07:06:15

相关问题