假设我有很多报告目录,并且report.md
在包含报告的目录中总是有一个文件,但report.pdf
仅在已完成的报告中。我想找到report.md
存在但没有report.pdf
.
reports_dir
|
+-- project_xyz
| +-- report.md
| +-- image.png
|
+-- bugs
| +-- report.md
| +-- report.pdf
| +-- Makefile
|
+-- homework
+-- report.pdf
+-- test.md
如果我将此函数用作search "reports_dir" --include "report.md" --exclude "report.pdf"
,它应该返回/project_xyz
,但不会/bugs
返回/homework
sh
在/中进行此类搜索的最快方法是什么bash
? (单行优先)
答案1
for f in "$1"/*/"$2"; do dir=$(dirname -- "$f"); [ -f "$dir/$3" ] || printf '%s\n' "$dir"; done
将脚本另存为search
.第一个参数是父目录,第二个参数是包含目录,第三个参数是排除目录。
sh search "reports_dir" "report.md" "report.pdf"
"$1"/*/"$2"
report.md
仅获取示例中文件的路径。dir=$(dirname -- "$f")
获取这些文件的目录路径(假设它不以换行符结尾)。[ -f "$dir/$3" ]
测试该目录 ( ) 中第三个参数中的文件是否存在,report.pdf
这就是常规的类型(不是目录、fifo、设备...)。|| printf '%s\n' "$dir"
如果它不存在(或者不是常规的文件),打印目录名称。
答案2
和zsh
:
print -rC1 -- **/report.md(DN^e['[[ -e $REPLY:r.pdf ]]']:h)
将print
r
aw on 1
C
olumn任何级别的子目录 ( ) 下的文件h
的 ead (dirname),包括ot (隐藏)文件,对于这些子目录,代码的评估不会 ( ) 返回 true (其中包含文件的 oot 名称在哪里)查看)。report.md
**/
D
e
[[ -e $REPLY:r.pdf ]]
^
$REPLY:r
r
$REPLY
通过允许嵌入参数和任何类似 Bourne 的 shell(包括)的find
实现(例如 GNU ) ,您可以执行以下操作:find
{}
-exec
bash
find . -type d -exec test -e '{}/report.md' \; \
! -exec test -e '{}/report.pdf' \; -print
但这意味着每个目录最多执行 2 个test
命令。
通过bosh
其find
内置功能,可以通过以下方式避免这种情况:
find . -type d -call '
[ -e "$1/report.md" ] && [ ! -e "$1/report.pdf" ]' {} \; -print
这次,-call
shell 直接解释该代码并调用内置的[
.
POSIXly:
find . -type d -exec sh -c '
for d do
[ ! -e "$d/report.md" ] || [ -e "$d/report.pdf" ] || printf "%s\n" "$d"
done' sh {} +
对于那些内置的sh
实现(现在大多数),应该相对有效,因为调用它来处理它找到的目录列表的次数尽可能少。[
printf
sh
find
答案3
您可以使用简短的 bash 单行语句来测试 PDF 是否存在(-exec
也是一个过滤器):
find . -name '*.md' -exec bash -c '[[ -f "${1%.*}.pdf" ]] && exit 1; exit 0;' bash-line {} \; -print
如果您只需要目录名称,您也可以将其放在-exec
第一个目录之后的另一个目录中(find
在第一个测试后停止):
find . -name '*.md' -exec bash -c '[[ -f "${1%.*}.pdf" ]] && exit 1; exit 0;' bash-line {} \; -exec dirname {} \;
答案4
也许这会起作用?
comm -23 <(find -name "report.md" -printf '%h\n' | sort) <(find -name "report.pdf" -printf '%h\n' | sort)