我是 bash 编程的新手(grep/uniq/sort/etc...),我无法尝试从给定格式的文件中删除重复项
--
name: joe
tag: 123
--
name: mike
tag: 000
--
name: dave
tag: 123
--
name: loopy
tag: 123
--
基本上我想要的是删除文件中具有相同标签号的重复项,如下所示:
--
name: joe
tag: 123
--
name: mike
tag: 000
--
这个任务非常适合 awk。如果你有 gawk 或 mawk 可用,你可以通过适当地设置记录分隔符来完成它:
awk -v RS='--\n' -v ORS='--\n' '!h[$4]++' infile
输出:
--
name: joe
tag: 123
--
name: mike
tag: 000
--
这通过记住已看到的标签 ( h[$4]++
) 起作用,即每条记录中的第四个元素。增量前面的 bang ( !
) 确保条件仅在h[$4]
为零时为真,因此默认规则 ( { print $0 }
) 仅在第一次看到标签时调用。
稍短的版本:
awk '!h[$4]++' RS='--\n' ORS='--\n' infile
如果名称字段有空格,则字段计数会有所不同。您可以通过稍微不同的字段拆分来处理此问题:
awk '!h[$4]++' RS='--\n' ORS='--\n' FS='\n| *: *' infile
awk '/name/{x=$0}/tag/{a[$0]++;if(a[$0]<2){print "--\n"x,"\n",$0"\n--"}}' your_file
测试如下:
> cat temp
--
name: joe
tag: 123
--
name: mike
tag: 000
--
name: dave
tag: 123
--
name: loopy
tag: 123
--
> awk '/name/{x=$0}/tag/{a[$0]++;if(a[$0]<2){print "--\n"x,"\n",$0"\n--"}}' temp
--
name: joe
tag: 123
--
--
name: mike
tag: 000
--
/name/
{将行存储在一个变量中,这样如果下一个标签不是重复的,我们就可以使用这个临时变量。}
/tag/
{用行数构建一个关联数组。多于一个会导致重复。所以仅当计数为 1 时才打印}
如果 foobar 是包含删除重复行的文件:
awk '{ if (arry[$3]++ == 0) print $0; }' foobar
数组中的 $3 表示仅根据第 3 列中的值删除重复项。如果要删除整个重复行,请改用 $0。
以这种方式使用 awk 具有不改变输入行的顺序(sort/uniq 所做的)的额外优势。