파일에 일치 항목이 포함된 각 폴더에서 Grep을 실행하고 명령을 실행합니다.

파일에 일치 항목이 포함된 각 폴더에서 Grep을 실행하고 명령을 실행합니다.

나는 grep이 파일에서 일치하는 항목을 찾는 각 폴더에서 명령을 실행하는 우아한 방법을 찾고 있습니다. find플래그는 -execdir내용이 아닌 폴더/파일 이름만 검색한다는 점을 제외하면 find 와 매우 유사합니다.

현재 나는 다음과 같은 것을 사용하고 있습니다.

grep -r "pattern" --include=\*.out -l | xargs -L 1 bash -c 'cd `dirname "$0"` && some_script.sh'

더 직접적인 방법이 있나요? 그것은 마치 grep ... -execdir?

답변1

find실행할 수 있습니다 grep:

find . -type f -name '*.out' \
    -exec grep -q -e 'pattern' {} \; \
    -execdir somescript.sh \;

발견된 각 경로 이름 에 대해 패턴이 파일의 행과 일치하는지 확인하는 .out데 사용됩니다 . grep그렇다면 찾은 파일의 디렉터리를 작업 디렉터리로 사용하여 실행하는 -execdir데 사용됩니다 .somescript.sh

somescript.sh이것이 작동하려면 어딘가에서 사용할 수 있어야 하며 스크립트 는 일치하는 파일이 포함된 각 디렉터리 $PATH에 대해 한 번이 아니라 발견된 각 파일에 대해 한 번 실행됩니다 .out.

.out일치하는 파일이 포함된 각 디렉터리에서 스크립트를 한 번만 실행합니다.

find . -type d -exec sh -c '
    for dirpath do
        if grep -q -e "pattern" "$dirpath"/*.out 2>/dev/null; then
            ( cd "$dirpath" && exec somescript.sh )
        fi
    done' sh {} +

find파일이 아닌 디렉터리를 찾는 데 사용됩니다 . 배치 디렉토리가 발견되면 짧은 인라인 쉘 스크립트가 실행됩니다. 셸 스크립트는 각 디렉터리의 모든 파일( 숨겨진 디렉터리를 찾는 동안 숨김 .out파일 제외)에 대해 패턴을 일치시키려고 시도하고, 일치하는 파일이 있으면 작업 디렉터리가 변경되는 하위 셸을 시작하고 스크립트를 실행합니다.findsomescript.sh

답변2

일치하는 파일이 하나 이상 포함된 각 디렉터리에 대해 out한 번만 스크립트를 실행 하고 grep각 파일에 대해 하나씩 실행하지 않으려면 다음을 수행할 수 있습니다.

P="pattern" find . -name '*.out' -type f -exec gawk '
  BEGINFILE {
    dir = FILENAME; sub("/[^/]*$", "", dir)
    if (dir in found) nextfile
  }
  $0 ~ ENVIRON["P"] {
    printf "%s\0", dir
    found[dir]
    nextfile
  }' {} + | xargs -r0 sh -c '
    for dir do
      (cd "$dir" && exec somescript.sh)
    done' sh

이는 가능한 한 적은 수의 프로세스를 실행하고 gawk가능한 한 적은 수의 파일을 읽습니다(각 파일의 내용은 가능한 한 적습니다).

GNU xargs또는 호환 파일 이름에는 현재 로케일에서 유효한 문자를 형성하지 않는 일련의 바이트가 포함되어 있지 않다고 가정합니다.

GNU grep호출(및 GNU dirname, sort, xargs) 사용:

grep -rlZ --include='*.out' pattern . |
  xargs -r0 dirname -z |
  sort -zu |
  xargs -r0 sh -c '
    for dir do
      (cd "$dir" && exec somescript.sh)
    done' sh

out이전 솔루션과 달리 이 방법은 일치하는 파일이 발견된 디렉터리의 파일까지 포함하여 모든 파일을 찾습니다 . GNU는 grepgrep보다 더 효율적이므로 gawk얼마나 많은 초과 데이터가 greping되는지에 따라 여전히 더 효율적일 수 있습니다.

관련 정보