我想我已经知道这个问题的答案,答案是“做工作”(即循环文件中的各个条目),但我想看看是否有人有任何 Bash 魔法。
情况:
假设我有一个目录:/mnt/Transfer/Downloads/Documents/Thesis/Drafts/images/
我有一个包含目录列表的文件:
/mnt/Transfer/Downloads/Documents/ProjectProposal/
/mnt/Transfer/Downloads/Documents/ProjectDesign/
/mnt/Transfer/Downloads/Documents/Thesis/Drafts/
...
问题:
Bash 脚本中有没有一种快速简便的方法(甚至可能是单行?)来检查列表文件中的任何目录是否是第一个目录的子目录,而无需简单地循环遍历文件?即检查列表文件中的任何目录是否是某个目录的子目录?
编辑以进一步澄清:如果我有/foo/mnt/Transfer/Downloads/Documents/ProjectProposal/
,我想知道列表文件(即/foo/mnt/Transfer/Downloads/
)中是否有包含它的子目录。字符串匹配就足够了;无需检查目录是否确实存在。
我已经实现了类似的东西,grep -q $FILEDIRECTORY $accessLog
但这是一个更简单的情况,我根据列表文件条目 grep 了一个单独的目录。现在我想走相反的方向,基本上针对单个目录“grep”列表文件中的单个整体。
如果我必须做一个循环,那就是我要做的,我只是有兴趣学习是否有“更好的方法”。
提前致谢!
答案1
using 的缺点grep
是,要么需要允许正则表达式,以便可以将模式匹配绑定到字符串的开头,要么需要禁用正则表达式并希望每个模式和目标匹配都有一个公共且不重复的前缀。
正则表达式的问题在于像这样的模式^/mnt/one.two/
将匹配字符串/mnt/one/two/
。固定字符串的问题是/mnt/one/two/
可能匹配/one/two/
.
另一种方法是依次awk
比较目标目录路径与每一行,确保目标的开头和模式的开头对齐。假设您的目录列表位于file
:
dir="/mnt/Transfer/Downloads/Documents/Thesis/Drafts/images/"
awk -v dir="$dir" '$0 == substr(dir, 1, length($0))' file
你的例子的输出是
/mnt/Transfer/Downloads/Documents/Thesis/Drafts/
答案2
什么时候
$ dir="/mnt/Transfer/Downloads/Documents/Thesis/Drafts/images/"
$ cat file
/mnt/Transfer/Downloads/Documents/ProjectProposal/
/mnt/Transfer/Downloads/Documents/ProjectDesign/
/mnt/Transfer/Downloads/Documents/Thesis/Drafts/
...
那么,如果您只关心是否存在匹配项而不关心文件中的哪一行匹配:
if echo "$dir" | grep -q -f file; then
echo "a match exists in the file"
else
echo "no match"
fi
答案3
与perl
的rindex
:
dir=/mnt/Transfer/Downloads/Documents/Thesis/Drafts/images/
perl -lsne 'print if rindex($dir, $_, 0) == 0' -- -dir="$dir" < file