긴 이야기 짧게(너무 길어서 다 못끝냈어요)

긴 이야기 짧게(너무 길어서 다 못끝냈어요)

.txt라는 파일이 포함된 모든 디렉터리에서 명령(make 명령과 유사)을 실행하는 스크립트를 만들고 싶습니다 my_suites.cfg.

답변1

find지정된 파일이 있는 작업 디렉터리(예: pwd)를 사용하여 명령을 실행할 수 있습니다 .

find /path/to/repository -type f -name my_suites.cfg -execdir pwd \;

/path/to/repository는 상대 경로일 수도 있습니다("."도 가능).

답변2

라벨에 표시된 대로 bash다음 globstar옵션을 사용할 수 있습니다.

shopt -s globstar
for d in **/; do if [[ -f "$d/my_suites.cfg" ]]; then cd "$d"; make; cd -; fi; done

이는 현재 디렉토리의 모든 디렉토리와 하위 디렉토리를 반복하고, 파일이 my_suites.cfg존재하는지 확인하고, 그렇다면 해당 디렉토리를 변경하고 를 호출한 make다음 원래 디렉토리로 다시 변경합니다.

답변3

따라서 문제를 요약하면 특정 이름을 가진 각 파일에 대해 한 번에 하나씩 bash 명령을 실행하려고 합니다.

처음부터 모든 것을 직접 작성하는 대신 기존 도구를 사용하겠다고 가정하면 다음과 같은 몇 가지 아이디어가 있습니다.

긴 이야기 짧게(너무 길어서 다 못끝냈어요)

최신 파일이 아직 인식되지 않았는지 여부는 중요하지 않습니다.

$ mlocate --basename --regex "^my_suites.cfg$" \
| xargs dirname \
| xargs -d '\n' <command-to-run-on-the-file>

그렇지 않고 효율성이 그다지 중요하지 않은 경우( ~홈 디렉토리에서만 재귀적으로 검색한다고 가정):

$ find ~ -name "my_suites.cfg" -type f \
| xargs dirname \
| xargs -d '\n' <command-to-run-on-the-file>

풀 버전

파일 찾기

찾고 있는 파일이 시스템 전체에 분산되어 있는 경우 유효성에 대해 걱정해야 합니다.

더 빠른 방법

몇 가지 단점이 있습니다.

$ mlocate --basename --regex "^my_suites.cfg$"
  • mlocate대부분의 배포판에 대해 매일 업데이트되는 데이터베이스에서 파일 경로를 찾으세요. 따라서 최근에 생성되었거나 최근에 이동된 파일을 인식하지 못할 수 있습니다. 그러나 파일 시스템 자체를 통하지 않고 데이터베이스를 조사하기 때문에 검색이 매우 효율적입니다.
  • --basename옵션은 경로/디렉토리를 제외하고 찾고 있는 파일의 직접 이름을 지정합니다.
  • --regex옵션을 사용하면 검색 패턴에 정규식을 사용할 수 있습니다. ( ^문자열은 거기서 시작하고 $ 문자열은 거기서 끝날 것으로 예상됩니다.)

"항상 최신 상태" 접근 방식

$ find / -name "my_suites.cfg" -type f
  • find기본적으로 찾을 수 있는 모든 폴더를 탐색하고 my_suites.cfg라는 이름의 모든 파일을 나열합니다. 많은 읽기 작업을 수행해야 하기 때문에 검색하는 폴더가 많을수록 속도가 느려집니다.
  • -name옵션은 my_suites.cfg가이름우리가 찾고 있는 파일이 포함된 폴더가 아닌 파일의 디렉터리입니다.
  • -type옵션은 우리가 찾고 있는 것을 지정합니다.문서, 디렉토리, 심볼릭 링크, 소켓 또는 기타 항목에는 적용되지 않습니다.

각 파일에 대해 사용자 정의 명령 실행

...그게 xargs목적 이야

간단한 예

$ echo "some simple example" | xargs mkdir
$ # now there are three directories, named by the echoed words
$ ls
example  simple  some

좀 더 복잡한 것:

$ echo "hello world" | xargs -d ' ' -I % echo 'Print a word: %'
Print a word: hello
Print a word: world

  • -d옵션: 인수를 서로 구분하는 문자를 지정합니다(여기서는 공백).
  • -I옵션: 주어진 문자(이 경우)의 모든 발생은 파이프(이전)의 인수 %로 대체 됩니다.|

위의 예에서는 다음과 같은 일이 발생합니다.

  1. echo"hello world"를 표준 출력( stdout)으로 인쇄합니다.
  2. Pipe( |)는 이 값("hello world")을 다음 명령에 공급합니다 xargs.
  3. xargs매개변수에서 구분 기호 발생을 검색하고 구분 기호가 있는 매개변수를 분할합니다.
  4. xargs명령을 실행하는 대신 새로 생성된 매개변수를 반복하고 매개변수 값을 사용합니다.%

추가 읽기

관련 정보