찾기 명령: 목록의 이름

찾기 명령: 목록의 이름

이름 목록이 포함된 파일이 있습니다.

john
paul
ringo
george
...

그런 다음 다양한 이름을 가진 여러 파일이 있습니다.

maria.iso
jose.iso
pablo.iso
john.iso
jack.iso
jane.iso
...

find파일 목록 중 하나와 이름이 같은 파일만 출력하거나, 일치하는 항목이 없으면 파일을 출력하지 않는 명령을 실행하고 싶습니다 . 내 예에서는:

john

이 같은:

find . -type f -name "*.iso" (in array)

그러나 이것이 가능한지, 그렇다면 어디서부터 시작해야 할지 모르겠습니다.

지금까지 내 유일한 아이디어는 for 루프를 작성하는 것이었지만 이는 추악하고 비효율적으로 보입니다.

감사해요

답변1

readarray이름을 배열로 읽는 데 사용됩니다 names. 그런 다음 배열의 각 요소를 반복하여 명령을 실행합니다 find.

readarray names < names.txt

for n in ${names[@]};do
    find . -type f -name "${n}.iso"
done

답변2

find다음에서 "또는" 테스트를 수행할 수 있습니다 find . -name a -o -name b ....

따라서 파일을 수정하여 스위치를 추가하고 xargsbuild find 명령을 사용하십시오.

awk 'NR > 1 {print "-o"}; {print "-name", $0".iso"}' input-file | xargs find . 

충분히 작은 목록의 경우 하나만 실행해야 합니다 find. 파일 이름에 공백, 따옴표 또는 기타 특수 문자가 있는 경우 ASCII 널 문자로 구분된 레코드 사용을 고려하십시오(이 경우 GNU sed를 사용하여 입력을 수정할 수 있습니다). .

답변3

다음 명령을 사용하면 더 쉬울 것입니다 zsh.

names=(${(f)"$(<name-list.txt)"})

ls -ld -- **/(${(~j[|])names}).iso(D)

어디:

  • $(<file)ksh 스타일 연산자, 다음으로 확장 가능file
  • f매개변수 확장은 라인의 분할을 표시 f하므로$namesname-list.txt
  • j[|]: 배열 요소를 연결하는 데 with를 사용합니다.|
  • ~|리터럴이 아닌 전역 연산자(여기에서는 대체에 사용됨)로 생각하십시오 |.
  • **/: 재귀 와일드카드(모든 수준의 하위 디렉터리에서 검색)
  • (D):glob 한정자 dotglob(숨겨진 파일 포함 및 숨겨진 디렉터리 검색 포함 find)는 glob을 활성화합니다.

관련 정보