使用Bash循环遍历txt文件中的唯一行

时间:2015-06-30 21:21:41

标签: linux bash shell loops xslt

我在txt文件中循环显示制表符分隔的行。此txt文件是xml / xslt进程的输出,并且具有重复项。下面我正在寻找使用txt文件的解决方案,但使用XSLT的解决方案同样值得赞赏。请参阅示例txt文件。

txtfile.txt:第3行是第1行的副本

hello@example.com  running  1111
puppy@kennel.com   running  9876
hello@example.com  running  1111
husky@siberia.com  shutdown 1234
puppy@kennel.com   running  9876
hello@example.com  running  1111

我的问题是:可以在循环中跳过重复的行,以便循环只处理唯一的行吗?在这种情况下,如何配置循环线1,2,4和跳过线3,5,6?

我当前的工作循环读取重复项:

while read name status num
do
    echo "<tag1>"
    echo "<tag2>"$name"</tag2>"
    echo "<tag3>"$status"</tag3>"
    echo "<tag2>"$num"</tag2>"
    echo "</tag1>"

done < txtfile.txt

在我的txtfile中有数百行,近一半是重复的,所以这对我来说是个大问题!任何想法/解决方案赞赏。在此先感谢。

2 个答案:

答案 0 :(得分:2)

我建议使用awk:

$ awk '!a[$0]++{print "<tag1>\n<tag2>" $1 "</tag2>\n<tag3>" $2 "</tag3>\n<tag2>" $3 "</tag2>\n</tag1>"}' file
<tag1>
<tag2>hello@example.com</tag2>
<tag3>running</tag3>
<tag2>1111</tag2>
</tag1>
<tag1>
<tag2>puppy@kennel.com</tag2>
<tag3>running</tag3>
<tag2>9876</tag2>
</tag1>
<tag1>
<tag2>husky@siberia.com</tag2>
<tag3>shutdown</tag3>
<tag2>1234</tag2>
</tag1>

条件!a[$0]++在第一次看到每一行时评估为true,之后为false。条件为真时,将打印输出。

基本原则是行$0的内容用作数组a中的键。如果记录之间的间距可能不同,则可以使用!a[$1,$2,$3]++代替,只要3个字段相同,就会将行计为相同,无论它们之间的间距如何。

答案 1 :(得分:2)

您可以通过sort -u阅读该文件以消除重复的行:

sort -u /your/file | while read ...