보고서 디렉터리가 많고 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)
코드 평가가 true(파일의 oot 이름이 포함된 경우)를 반환하지 않는 ot(숨겨진) 파일을 포함하여 모든 레벨 하위 디렉터리() 아래에 있는 파일의 olumn ead(dirname) print
r
에 대해 aw를 확인 합니다 . ).1
C
h
report.md
**/
D
e
[[ -e $REPLY:r.pdf ]]
^
$REPLY:r
r
$REPLY
내장된 인수와 Bourne 유사 셸(GNU 포함) 구현을 허용하면 find
다음을 수행할 수 있습니다.find
{}
-exec
bash
find . -type d -exec test -e '{}/report.md' \; \
! -exec test -e '{}/report.pdf' \; -print
test
그러나 이는 디렉터리당 최대 2개의 명령을 실행한다는 의미입니다 .
내장된 기능을 사용하면 다음과 같은 방법으로 이러한 문제를 방지할 수 bosh
있습니다 .find
find . -type d -call '
[ -e "$1/report.md" ] && [ ! -e "$1/report.pdf" ]' {} \; -print
이번에는 -call
쉘이 코드를 직접 해석하고 내장된 [
.
POSIX적으로:
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)