我有 2 个名为 one.txt 且带有重复项的 txt 文件:
yesterday
yesterday
today
today
tomorrow
tomorrow
第二个 txt 名为 two.txt,其中包含重复项:
mike
mike
paul
paul
tomorrow
tomorrow
使用该命令sort -u one.txt > total.txt
我可以得到一个输出文件:
today
tomorrow
yesterday
因此,我使用sort -u two.txt >> total.txt
将第二个文件添加到同一输出文件中,结果为:
today
tomorrow
yesterday
mike
paul
tomorrow
我确实有两次“明天”这个词。如何避免呢?
sed 's/[[:space:]]+$//' one.txt two.txt | sort -u total.txt
似乎是解决方案,但每次我想添加另一个单词列表时都会出现问题,例如:
sed 's/[[:space:]]+$//' three.txt | sort -u total.txt
答案1
如果您愿意按total.txt
排序顺序(以mike
和paul
开头),您可以执行以下任一操作:
sort -u one.txt two.txt > total.txt
或者sort -u total.txt two.txt -o total.txt
如果需要保持顺序(one.txt
先排序的内容,后排序的内容two.txt
除了)中的行one.txt
,然后执行
sort -u two.txt | awk '!seen[$0]++' total.txt - > temp.txt; mv temp.txt total.txt
这相当于
(cat total.txt; sort -u two.txt) | awk '!seen[$0]++' > temp.txt; mv temp.txt total.txt
即,获取 的内容total.txt
(已经排序和去重),跟随 的排序、去重的内容two.txt
,并通过先前记录的
awk
命令对未排序的文件进行重复数据删除。
答案2
您可以使用sed
plussponge
安全地覆盖输入文件。这允许您用作total
输入文件 -sponge
在软件包(Ubuntu)中可用moreutils
。
Sponge 读取标准输入并将其写入指定文件。与 shell 重定向不同,sponge 在打开输出文件之前吸收所有输入。这允许构建读取和写入同一文件的管道。
file[0]=total; [[ -f "$file" ]] || touch "$file"
file[1]=any
file[2]=number
file[3]=of
file[4]=files
sed 's/[[:space:]]\+$//' "${file[@]}" | sort -u | sponge "$file"
请注意,bash var 数组中的第一项${file[0]}
可以被引用并设置其值,而无需使用索引,即。$file
(正如我上面所做的 - 它只是更容易打字)。如果尚未退出,则创建
。 您可以使用任意数量的文件 - 只需相应地增加索引号即可。 您可以重新运行同一组文件,并且内容将保持与第一次运行相同(对于该组文件)[[ -f total ]] || touch total
total
total
而不是sponge
您可以只输出到临时文件,然后替换total
为该临时文件(但我喜欢sponge
)