任何人都可以帮助如何比较文本文件中的两个连续行的第一个字符,如果两个第一个字符相同,则忽略/删除第二行并仅将第一行打印到新文件中。
#1001
#1002
mango
orange
grape
#1003
我想删除#1002
。
答案1
使用 GNUuniq
和-w
选项1:
-w, --check-chars=N
compare no more than N characters in lines
您可以省略连续的重复行,只比较第一个字符:
uniq -w1 infile >outfile
1. 这对于多字节字符不能正常工作。请参阅下面 Stéphane 的注释
答案2
perl -C -ne '$c = substr($_,0,1);
print unless $c eq $l;
$l = $c;' < file.in > file.out
答案3
sed '$n;h;N;/^\(.\).*\n\1/g;/\n/P;//!G;D' <in >out
有一个sed
脚本可以做到这一点。
它的工作原理如下:
- 如果当前行是最后一行,则将其打印到标准输出并结束脚本。
- 如果没有,请保存当前行的副本以保留空间。
- 然后将下一个输入行附加到模式空间。
- 如果模式空间中的第一个字符与刚刚附加的行中的第一个字符相同,则使用保存的保留空间副本覆盖模式空间。
- 如果没有,那么我们在模式空间中仍然会有一条
\n
行,在这种情况下,我们应该只打印到该点。 - 如果没有,请将我们保留的行的另一个副本附加到模式空间。
- 无论如何,删除模式空间中的第一个换行符,然后从脚本的顶部开始保留剩余的内容。
本质上,它一次工作两行,当第二行中的第一个字符与第一行的第一个字符不匹配时,仅打印第一行,并递归地覆盖与系列中第一次出现的字符相同的字符。因此,它可以快速有效地以最小的缓冲处理任何大小的输入,并将任何大小的第一个字符匹配系列压缩到仅第一次出现。它将使用实时输入或文件,但它只需要读取或存储当前行和下一行的副本。
答案4
perl -0777 -pe '1 while s/^(.)(.*)\n\1.*/$1$2/gm' file.in >file.out
这会吞噬整个文件,并循环直到找不到更多匹配项。