如何在Bourne Shell脚本中移除文本文件重复行?求助排查代码问题
解决Bourne Shell脚本批量去重.txt文件内容的问题
我看你是想批量处理FilePath/test/下所有子目录里的testfile.txt,移除重复内容——你的示例输入是asdfg, test efgrso, test asdfg, test asdfg, test,期望输出是asdfg, test efgrso, test,但试了脚本里的awk和sort命令都没生效,我帮你找找问题,再给你修正后的方案。
先看你原脚本的几个问题
- 你用了
##注释awk命令,在Bourne Shell里##是参数扩展语法,不是注释,这导致你的awk命令根本没执行!要注释单行得用单个# - 变量引用没加双引号,比如
cd $dir如果目录名里有空格会直接报错,必须写成cd "$dir" - 脚本里换行和分号混用太乱,可读性差还容易出语法错误
分两种场景给你解决方案
场景1:文件是每行一个条目(比如你的示例其实是换行后的内容)
如果你的testfile.txt实际内容是每行一个条目,比如:
asdfg, test efgrso, test asdfg, test asdfg, test
那用行去重就可以,修正后的脚本如下:
for dir in FilePath/test/*; do echo "Directory $dir" # 先判断是不是目录,避免处理非目录文件 if [ -d "$dir" ]; then # 方案1:用awk保留首次出现的行,不改变原有顺序 /usr/xpg4/bin/awk '!seen[$0]++' "$dir/testfile.txt" > "$dir/testfile.txt.tmp" && mv "$dir/testfile.txt.tmp" "$dir/testfile.txt" # 方案2:用sort -u去重,但会改变行的顺序 # sort -u "$dir/testfile.txt" > "$dir/testfile.txt.tmp" && mv "$dir/testfile.txt.tmp" "$dir/testfile.txt" fi done
解释:
- 加了
[ -d "$dir" ]判断,避免FilePath/test/下有非目录文件导致报错 - 用临时文件重定向再替换原文件,因为awk/sort不能直接原地修改文件(直接用
> "$dir/testfile.txt"会先清空原文件) - 两个方案二选一:awk会保留原来的行顺序,sort -u会把行排序后去重
场景2:文件是单行内的重复字段(就是你给出的示例那样整行都是重复条目)
如果你的testfile.txt里只有一行,内容是asdfg, test efgrso, test asdfg, test asdfg, test,要把重复的asdfg, test这类字段去掉,那需要用另一种处理方式:
for dir in FilePath/test/*; do echo "Directory $dir" if [ -d "$dir" ]; then # 把单行按空格分割成字段,去重后再拼接成一行 awk '{ for (i=1; i<=NF; i++) { if (!seen[$i]++) { printf "%s ", $i } } printf "\n" }' "$dir/testfile.txt" > "$dir/testfile.txt.tmp" && mv "$dir/testfile.txt.tmp" "$dir/testfile.txt" fi done
这个脚本会把单行里的重复字段(按空格分割)去掉,保留首次出现的字段,最后输出一行干净的内容。
最后验证一下
不管用哪个方案,执行完脚本后,你可以查看testfile.txt的内容,应该就能得到你期望的asdfg, test efgrso, test了。
内容的提问来源于stack exchange,提问作者Zoelte
相关产品推荐
相关产品推荐

