.c와 Makefile이 모두 포함된 폴더가 있습니다. 어떤 폴더에 이 항목이 있는지 알아야 합니다. 이 폴더를 찾으려면 Linux에 어떤 명령을 입력해야 합니까?
답변1
그리고 zsh
:
has() ()(($#)) $REPLY/$~1(N)
ls -- **/*(/e{has Makefile}e{has \\*.c})
has
인수로 제공된 glob이 $REPLY
디렉터리의 모든 파일을 확인하는지 확인하는 함수로 정의됩니다. e
디렉토리 선택 여부를 결정하기 위해 glob 한정자에서 이 함수를 사용합니다 . 다음 zsh 기능 중 일부는 다음과 같습니다.
() {compound-command} arguments
: 익명 기능입니다. 여기서 함수의 코드는 다음과 같습니다(($#))
. 매개변수 수가 0이 아니면 true를 반환합니다.$~1
:zsh
매개변수 확장 중에는 기본적으로 분할+glob 작업이 수행되지 않습니다.$~1
요청하려면 명시적으로 요청해야 합니다.전반적인 상황확장된 부분은 패턴으로 간주$1
됩니다 .$1
(N)
: 활성화된 전역 한정자빈 공이 glob의 경우 어떤 파일과도 일치하지 않으면 아무것도 확장하지 않도록 glob에 지시합니다.**/
: 모든 수준의 하위 디렉터리(/e...)
/
: 파일 유형에만 일치 하는 또 다른 glob 한정자목차및e{code}
일치하는 파일암호true로 확인됩니다(파일은 에 저장됨$REPLY
).
D
숨겨진 디렉터리를 보고 숨겨진 파일을 고려하려면 c
일부 glob 한정자를 추가하세요.
printf '%s\n' **/*(D/e{has Makefile}e{'has "*.c(#qD)"'})
GNU 도구 사용:
LC_ALL=C find . \( -name '*.c' -o -name Makefile \) -print0 |
LC_ALL=C awk -v RS='\0' -v ORS='\0' '
{dirname = $0; sub("/[^/]*$", "", dirname)}
/\.c$/ {hasc[dirname]; next}
{hasMakefile[dirname]}
END {for (dir in hasc) if (dir in hasMakefile) print dir}' |
xargs -r0 ls
숨겨진 디렉터리로 들어가고 싶지 않고 숨겨진 C 파일에 관심이 없다면 명령을 find
다음과 같이 변경하세요.
LC_ALL=C find . -name '.?*' -prune -o \( -name '*.c' -o -name Makefile \) -print0
이는 일치하는 디렉터리의 경로와 내용을 제공하지만 일치하는 디렉터리가 하나만 있는 경우 ls
해당 경로는 출력되지 않습니다. 경로를 디렉터리와 일치시키려는 경우에는 ls --
로 바꿀 수 있습니다.printf '%s\n'
답변2
이것은 진지한 답변은 아니지만 이와 같은 질문은 때때로 SQL-in-Shell을 사용하거나 그 반대의 방법을 사용할 수 있기를 바랍니다.
find . -type f |
awk -F/ -vOFS=/ -vq=\' 'BEGIN{print "create table temp (dir varchar, f varchar);"}
{f=$(NF--); print "insert into temp values(" q $0 q "," q f q ");" }
END{print "select dir from temp group by dir ";
print "having sum(when f like "q"%.c"q" then 1 else 0 end)>0 ";
print "and sum(when f="q"Makefile"q" then 1 else 0 end)=1;"}
' | dosql
답변3
GNU find를 사용하면 다음과 같은 작업을 수행할 수 있습니다.
find . -type f -name Makefile \
-execdir sh -c '
find . ! -name . -prune -name \*.c -execdir pwd \; -quit
' \;
여기서 먼저 Makefile이라는 일반 파일을 찾은 다음 해당 파일을 찾으려는 디렉토리를 사용하여 sh를 시작하면 해당 디렉토리에서만 .c 파일을 찾고 첫 번째 .c 파일이 발견되면 디렉토리 이름을 인쇄합니다. c 즉시 종료합니다.