for 루프에서 Find 명령이 작동하지 않습니다.

for 루프에서 Find 명령이 작동하지 않습니다.

파일 이름 목록이 있고 경로를 얻을 수 있도록 명령을 찾기 위해 파일을 하나씩 제공하고 싶습니다. for 루프를 사용하고 cat 명령을 사용하여 변수의 모든 파일 이름을 가져온 다음 변수를 통해 하나씩 find 명령에 전달했지만 작동하지 않습니다. 누구든지 나를 안내할 수 있나요?

for f in $(cat filelist.txt)
do 
find /home/abc/ -type f -name "$f"
done;

오류는 발생하지 않지만 출력도 얻지 못하고 출력을 변수에 넣으려고 시도했지만 운이 없습니다.

답변1

각 줄에 저장된 파일 중 하나의 이름을 가진 파일을 찾으려면 s를 filelist.txt사용하는 간단한 방법이 있습니다 .zshglobbing

names=( ${(f)"$(<filelist.txt)"} ) &&
  (( $#names )) &&
  print -rC1 -- /home/abc/**/${(~j[|])names}(D.)

귀하의 접근 방식이 작동하지 않는 이유는 아무런 문제가 없지만 즉시 명확하지 않습니다.

  • 에서는 bash인용되지 않은 콘텐츠 쌍(zsh에서만 분할) $(cat filelist.txt)의 콘텐츠에 대해 Split+glob을 호출합니다 filelist.txt. 기본값 $IFS(분할 섹션의 경우)을 사용하면 줄 바꿈뿐만 아니라 공백과 탭에서도 분할됩니다. 그래서 그 안에 줄이 있으면 호출된 파일 이 아닌 호출된 파일과 호출된 파일을 my file.txt찾습니다.myfile.txtmy file.txt
  • file *이라는 파일이 있으면filelist.txt전반적인 상황섹션은 스크립트가 호출되는 디렉터리의 파일 목록으로 확장됩니다.
  • -name '*'이름이 지정된 파일 도 검색되지 않지만 *전달된 내용이 -name패턴으로 처리되므로 모든 파일이 보고됩니다. 와일드카드 연산자를 비활성화 하려면 이스케이프 [및 with 가 ?필요 합니다 .*\\

이제 귀하의 질문은 다음과 같습니다.

  • filelist.txtLF 대신 CRLF 구분 기호를 사용하는 MSDOS 텍스트 형식입니다. 이를 실행하여 dos2unix문제를 해결합니다.
  • 파일 경로 filelist.txt(예 dir/file.txt: )가 있습니다. -name파일 이름만 일치하므로 절대 일치하지 않습니다.

여기서 루프 대신 GNU를 사용할 수 있습니다 xargs.

xargs -rd'\n' -a filelist.txt -I NAME find /home/abc/ -name NAME -type f

그러나 이는 여전히 각 파일 이름 전체를 파악하는 것을 의미하며 /home/abc/이는 비효율적입니다.

대신 다음과 같이 할 수 있습니다.

xargs -rd'\n' -n200 -a <(sed 's/[*?\\[]/\\&/g' filelist.txt) sh -c '
  for name do
    set -- -o -name "$name"
    shift
  done
  shift
  find /home/abc/ \( "$@" \) -type f' sh

find /home/abc/ \( -name name1 -o -name name2... \) -type f한 번의 호출로 최대 200개의 이름을 호출할 수 있습니다 . find/home/abc, 1개만 호출하는 것만큼 좋지는 않지만 zsh훨씬 더 좋습니다.

sed또한 이름에는 이스케이프된 와일드카드 문자를 사용합니다 . 거기도 지나갈 수 있어요 dos2unix.

답변2

또한 시도

find -iname $(sed -z 's/\n$//; s/\n/ -o -iname /g' list.txt)

*nix 텍스트 파일에 있어서는 안 되는 문자 sed -z로 끝나는 줄을 찾아 \000전체 파일을 메모리에 로드합니다. 그런 다음 후행 <NL>문자를 제거하고 나머지 문자로 바꾸면 ed 파일 이름 의 긴 목록을 얻을 수 있습니다 -o -iname.findor

관련 정보