我想要一个在 Linux 上运行并且可以跨 shell(不仅仅是 bash)和文件系统(包括 drvfs 或 btrfs)移植的解决方案 注意:目录名称可能包含空格
通过 find,我可以生成以文件夹为根的所有路径的列表,如下所示:
find -type d
.
./a dir
./a dir/20210101
./a dir/20210101/bin
./a dir/20210101/etc
./a dir/20210101/var
./a dir/20210101/var/log
./a dir/20211201
./b dir
./b dir/20210212
./b dir/20210212/bin
./b dir/20210212/etc
./c dir
./d dir
./d dir/20210711
然而,我想排除已经包含在最深的唯一路径中的“基”或“父”路径。还请帮助使用正确的术语来描述这一点,因为我觉得我没有使用最佳的描述。
我可以使用基本脚本来完成此操作,但假设有一种更优雅的方法,使用以下方法之一:
- 寻找
- LS
这是我的脚本:
save_ifs=$IFS;
IFS=$'\n';
prev_path="";
for path in $(find -depth -type d); do
if [ ! ${#path} -lt ${#prev_path} ]; then
echo $path;
fi
prev_path=$path;
done
及其输出 - 这是所需的输出
./a dir/20210101/bin
./a dir/20210101/etc
./a dir/20210101/var/log
./a dir/20211201
./b dir/20210212/bin
./b dir/20210212/etc
./c dir
./d dir/20210711
答案1
这看起来像是相反的变体从文本文件中过滤掉比直接前一个路径更深的路径。
因此,修改我的答案,这是一个选择:
tac input.txt | awk '
{ sub(/\/?$/, "/") }
NR == 1 || substr(prev, 0, length($0)) != $0 { print }
{ prev = $0 }; ' | tac | sed -e 's/\/$//'
或者
cat input.txt | awk '
{ sub(/\/?$/, "/") }
NR != 1 && substr($0, 0, length(prev)) != prev {print prev}
{ prev = $0 }
END { print }; ' | sed -e 's/\/$//'
根据第一个列表中的输入,两者都会给出:
./a dir/20210101/bin
./a dir/20210101/etc
./a dir/20210101/var/log
./a dir/20211201
./b dir/20210212/bin
./b dir/20210212/etc
./c dir
./d dir
假设输入是有序的,以便目录的内容紧接在该目录之后(即深度优先,预先排序),这就是 的输出find
应该类似于(*)的内容,并且与 C 语言中的字典排序相匹配语言环境会给出。
(除非您使用-depth
,这与名称所暗示的不同,会切换到后排序,但仍然是深度优先搜索。)