일치하는 문자열이 있는 파일이 포함된 디렉터리 경로 추출

일치하는 문자열이 있는 파일이 포함된 디렉터리 경로 추출

results.out 파일을 포함하는 여러 수준의 하위 디렉터리가 여러 개 있습니다.

./dir1/results.out
./dir2/dir21/results.out
./dir3/dir31/dir311/results.out

이제 이러한 하위 디렉터리를 다른 위치로 이동해야 하므로 string1포함된 디렉터리 경로를 검색하고 추출 해야 합니다 . results.out예를 들어 다음 코드를 사용하여 파일 경로를 얻을 수 있습니다.results.outstring1

for i in $(find . -type f -name "results.out);
do
grep -l "string1" $i
done

디렉토리 경로만 얻으려면 위 코드를 어떻게 수정해야 합니까?

답변1

GNU가 있는 경우 형식 지정자를 사용하여 find경로를 인쇄 할 수 있습니다.%h

    %h     Leading directories of file's name (all but the last ele‐
           ment).  If the file name contains no slashes (since it is
           in  the  current  directory)  the %h specifier expands to
           ".".

예를 들어 당신은 할 수 있습니다

find . -name 'results.out' -exec grep -q 'string1' {} \; -printf '%h\n'

답변2

그리고 zsh:

print -rl ./**/results.out(.e_'grep -q string $REPLY'_:h)

이는 .( )라는 이름의 일반 파일을 재귀적으로 검색하여 results.out평가하는 경우 각 파일에서 실행됩니다.grep -q ...e진짜h경로의 시작 부분(마지막 요소가 없는 경로) 만 인쇄합니다 .


findsh및 확장을 사용하여 ${parameter%/*}헤더를 추출하는 또 다른 방법은 다음과 같습니다 .

find . -type f -name results.out -exec grep -q string {} \; \
-exec sh -c 'printf %s\\n "${1%/*}"' bang {} \;

답변3

for i in $(find . -type f -name "results.out);
do
grep -l "string1" $i ; exitcode=${?}
if [ ${exitcode} -eq 0 ]  # string1 is found in file $i
then
   path=${i%/*}
   echo ${path}
fi
done

답변4

내가 올바르게 이해했다고 가정하면 다음을 수행하고 싶습니다.

find . -type f -name "results.out" -exec grep -l "string1" {} \; | xargs dirname

첫 번째 부분은 일치하는 파일 이름을 가져온 다음 xargs가 이러한 파일 이름을 dirname 프로그램에 인수로 전달하여 경로에서 파일 이름을 "제거"합니다.

관련 정보