我需要在管道分隔文件中搜索特定文本,并删除与文本匹配的列。
例如: 我的档案
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
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 :(得分: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
至少有两种方法可以解决这个问题。一个是纯文本的:替换一个序列管道,零个或多个非管道,单词'test',零个或多个非管道,以及另一个带有单个管道的管道:
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
鉴于'test'这个词可以出现在第一列或最后一列,你必须更加努力地处理这些:
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.....
另一种方法是扫描每一行的字段,而不是打印那些包含'test'的字段。
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.....
答案 1 :(得分: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