我正在运行Linux并编写BASH脚本。
我有一个文本文件,每行都有一个绝对文件路径。我发现有时我的一个文本文件将具有相同的文件,但列在不同的路径下。我想删除包含相同文件的这些行,这样文件只表示一次。
例如,如果我有:
/path/to/number1/file1.txt
/path/to/number1/file2.txt
/path/to/number1/file3.txt
/path/to/number2/file3.txt
我希望生成的文件包含:
/path/to/number1/file1.txt
/path/to/number1/file2.txt
/path/to/number1/file3.txt
路径长度是可变的(例如,文件名不能保证在字段4中)。
我曾尝试使用uniq的类似问题的先前解决方案,但uniq似乎没有提供匹配最后一个字段的选项,也不允许设置分隔符。有什么解决方案?
答案 0 :(得分:2)
短 awk 解决方案:
awk -F'/' '!a[$NF]++' file
-F'/'
- 将/
视为字段分隔符
!a[$NF]++
- 确保仅输出唯一文件名(包含在最后一栏$NF
中)
输出:
/path/to/number1/file1.txt
/path/to/number1/file2.txt
/path/to/number1/file3.txt
答案 1 :(得分:1)
使用awk,你可以这样做:
awk -F\/ '{ path=""; if ( path1[$NF] == "" ) { print $0;path1[$NF]=$0 } }' filename
我们在awk中构建一个变量路径。文件名由$ NF表示(最后一个字段用/分隔)。我们使用相关路径构建一个文件名(path1)数组。对于文件中的每个记录/行,引用此数组以检查文件名是否存在路径条目。如果有条目,则忽略记录,因此停止任何复制,否则打印路径
答案 2 :(得分:1)
使用纯粹的bash内置解决方案是一种富有表现力的解决方案。
将关联数组作为集合,您可以通过不断检查密钥是否已被使用来实现,在这种情况下,您只需继续循环。
# We will have a set which will contain existing filenames as keys.
declare -A fileSet
while read fullPath; do
fileName="${fullPath##*/}" # basename
if [ ! -n "${fileSet[$fileName]}" ]; then # If the file is not already in the set.
echo $fullPath >> $FILEOUTPUT
fileSet[$fileName]=1
fi
done < $FILEINPUT