Linux에서 find 명령을 사용하여 이전 명령에서 생성된 파일 이름 찾기

Linux에서 find 명령을 사용하여 이전 명령에서 생성된 파일 이름 찾기

find이런 명령어를 사용하려고 하는데

cut -f 4 file.txt | awk 'NR>1' | find ./ -name 

awk 명령 후 내 입력은 다음과 같습니다

foo.c
foo.txt
abc.txt

이전 명령의 파일 이름을 find 명령에 제공하려면 어떻게 해야 합니까?
따라서 기본적으로 foo.c경로를 찾고 얻은 다음 foo.txt경로를 얻는 등의 작업이 수행됩니다.

답변1

find여기서는 각 파일을 찾고 awk원하는 이름을 가진 파일을 선택하는 것이 더 쉽습니다 . 예를 들어, awk레코드 구분 기호를 NUL로 설정하는 것을 지원한다고 가정합니다.

find . -print0 | awk '
  ! names_loaded {if (NR>1) names[$4]; next}
  $NF in names' FS='\t' file.txt names_loaded=1 FS=/ RS='\0' -

답변2

각 옵션에 대해 여러 가지 옵션을 개별적으로 추가해야 합니다 -name. 이 시도:

IFS='
'
set -o noglob
find . -false $(awk -F '\t' -v OFS='\n' '
    NR>1 && $4 != "" { print "-o", "-name", $4}' file.txt)

awk한 줄에 하나의 인수를 인쇄하려면 $(...)쉘에서 분할+글로브 연산자(따옴표 없이)를 사용합니다.전반적인 상황부분적으로 장애가 있고나뉘다개행으로 분할되도록 부분적으로 조정되었으므로 에 인수로 전달하면 됩니다 find.

file.txt크기가 크면 실패할 수 있습니다. 또한 이름은 패턴으로 처리됩니다. 예를 들어, 가 포함된 줄이 있으면 이름이 로 시작하는 파일이 아닌 이름이 [f]ile*로 시작하는 모든 파일을 찾습니다 .file[f]ile*

정상그리고 안전이 계약에는 다음이 사용됩니다 xargs.

something something | xargs -r0 find . -false

그러나 여러 번 xargs실행 find하고 인수 목록을 an -o과 a -name또는 -name실제 파일 이름 사이에 분할하는 것이 가능합니다. 3의 배수인 임의의 숫자를 전달하여 -n 150이를 방지 할 수 있으며, 해당 숫자가 매개변수 크기 제한 내에 들어갈 만큼 충분히 작기를 바랍니다.

이를 먼저 배치하면 -false나머지 처리가 단순화됩니다. 이렇게 하면 -o-name.

find비표준 조건자를 지원하지 않는 경우 이를 -links 0거짓으로 보장된 다른 것으로 바꿀 수 있습니다.

답변3

zsh대신 여기에서 재귀 글로브를 사용하여 find더 쉽게 만들 수 있습니다.

filenames=( ${(f)"$(<file.txt tail -n +2 | cut -f 4)"} )
print -rC1 -- **/(${(~j[|])filenames})(ND)

우리가 사용한다면f 매개변수 확장 플래그cutlineeed에서 출력을 분할 f하고 ~j[|]교대 glob 연산자를 사용하여 임의 개수의 하위 디렉터리, dotglob 및 nullglob에 대해 배열 구성원을 연결합니다.|**/DN

일치 항목이 열에 표시됩니다 print.r1 C

이름이 파일 이름이 아닌 패턴으로 해석되는 경우 다음과 같이 변경할 수 있습니다.

print -rC1 -- **/(${(j[|])~filenames})(ND)

여기서 globsubst는 oin 플래그 에 의해 도입된 ~확장뿐만 아니라 전체 확장에 적용됩니다 .|j

답변4

find전체 출력을 로 보내고 해시 awk테이블을 사용하여 원하는 이름을 검색합니다. 기본적으로는 다음과 같습니다.

Awk='
#.. Extract required names from list.
FS == " " { if (FNR > 1) Name[$4]; next; }
#.. List paths for given names.
$(NF) in Name { print; }
'
find . -type f -print0 | awk "${Awk}" FS=' ' "file.txt" RS=$'\0' FS='/' - | sort

정렬은 이름별로 출력을 수집합니다(디렉터리 트리에 중복이 있을 수 있음).

Name[]배열의 적중 수를 계산하고 적중이 없는 이름을 END 블록에 나열하는 것이 개선될 수 있습니다 .

find출력은 null로 종료되고( find -print0에서는 awk에서 RS와 같이 NUL) 파일만 참조됩니다(제공된 이름과 일치하는 예기치 않은 디렉터리는 다른 솔루션에서 문제가 됩니다).

관련 정보