bash 用于识别包含“a.txt”和“b.txt”的子文件夹的脚本
bash script to identify sub-folder containing both `a.txt` and `b.txt`
给定一个包含许多深层嵌套文件夹的工作目录,我想要一个脚本来列出所有子文件夹的裸文件夹路径,这些子文件夹直接包含 a.txt
文件和一个 b.txt
文件。
文件名是完全固定的,因此无需支持通配符/正则表达式(尽管很高兴知道该解决方案是否确实支持它。)
作为参考,接下来我将对脚本执行的操作是生成每个 a.txt
、b.txt
对的差异。但我不希望一旦我找到每一对就太难了。
当我说 'bash' 时,技术上我的意思是 Windows 10 上的 msysgit - git bash。但是我'我希望这些细节不重要
带有 find
和 bash
以及一个循环。
#!/usr/bin/env bash
find . -type d ! -name . -exec bash -O nullglob -O extglob -c '
for d; do
files=("$d"/@(a|b).txt)
if (( ${#files[*]} == 2 )); then
echo diff "${files[0]}" "${files[1]}"
fi
done
' _ {} +
.
是当前工作目录。
nullglob
可能不需要,只是我的习惯而已
- 由于
@(a|b).txt
模式,需要 extglob
,尽管它可以用 files=("$d"/[ab].txt)
替换而不需要 extglob
- 如果您对输出满意,请删除
echo
。
您只需要包含 a.txt
和 b.txt
的目录路径。
给定
$: find -name '[ab].txt'
./1/3/a.txt
./1/3/b.txt
./1/a.txt
./2/b.txt
尝试
shopt -s globstar # ** matches zero or more subdirs
for d in **/a.txt # match a variable depth for the loop var
do [[ -e "${d%/a.txt}/b.txt" ]] && echo "${d%/a.txt}"
done
1/3
globstar
让两个星号 (**
) 代表任意数量(零个或更多)的子目录,因此
$: echo **/a.txt
1/3/a.txt 1/a.txt
这将搜索限制为仅可能正确的路径。
[[ -e "${d%/a.txt}/b.txt" ]]
剥离已知文件并检查另一个文件,正确地 returns 仅 1/3
作为包含两个文件的单独目录。
它应该非常有效,如果有多个命中,它也能正常工作。
$: find -name '[ab].txt'
./1/3/a.txt
./1/3/b.txt
./1/a.txt
./2/4/5/a.txt
./2/4/5/b.txt
./2/b.txt
$: for d in **/a.txt; do [[ -e "${d%/a.txt}/b.txt" ]] && echo "${d%/a.txt}"; done
1/3
2/4/5
给定一个包含许多深层嵌套文件夹的工作目录,我想要一个脚本来列出所有子文件夹的裸文件夹路径,这些子文件夹直接包含 a.txt
文件和一个 b.txt
文件。
文件名是完全固定的,因此无需支持通配符/正则表达式(尽管很高兴知道该解决方案是否确实支持它。)
作为参考,接下来我将对脚本执行的操作是生成每个 a.txt
、b.txt
对的差异。但我不希望一旦我找到每一对就太难了。
当我说 'bash' 时,技术上我的意思是 Windows 10 上的 msysgit - git bash。但是我'我希望这些细节不重要
带有 find
和 bash
以及一个循环。
#!/usr/bin/env bash
find . -type d ! -name . -exec bash -O nullglob -O extglob -c '
for d; do
files=("$d"/@(a|b).txt)
if (( ${#files[*]} == 2 )); then
echo diff "${files[0]}" "${files[1]}"
fi
done
' _ {} +
.
是当前工作目录。nullglob
可能不需要,只是我的习惯而已- 由于
@(a|b).txt
模式,需要extglob
,尽管它可以用files=("$d"/[ab].txt)
替换而不需要extglob
- 如果您对输出满意,请删除
echo
。
您只需要包含 a.txt
和 b.txt
的目录路径。
给定
$: find -name '[ab].txt'
./1/3/a.txt
./1/3/b.txt
./1/a.txt
./2/b.txt
尝试
shopt -s globstar # ** matches zero or more subdirs
for d in **/a.txt # match a variable depth for the loop var
do [[ -e "${d%/a.txt}/b.txt" ]] && echo "${d%/a.txt}"
done
1/3
globstar
让两个星号 (**
) 代表任意数量(零个或更多)的子目录,因此
$: echo **/a.txt
1/3/a.txt 1/a.txt
这将搜索限制为仅可能正确的路径。
[[ -e "${d%/a.txt}/b.txt" ]]
剥离已知文件并检查另一个文件,正确地 returns 仅 1/3
作为包含两个文件的单独目录。
它应该非常有效,如果有多个命中,它也能正常工作。
$: find -name '[ab].txt'
./1/3/a.txt
./1/3/b.txt
./1/a.txt
./2/4/5/a.txt
./2/4/5/b.txt
./2/b.txt
$: for d in **/a.txt; do [[ -e "${d%/a.txt}/b.txt" ]] && echo "${d%/a.txt}"; done
1/3
2/4/5