배열에 추가된 명령 결과를 찾기 위해 반복하시겠습니까? 공백이 포함된 파일 이름은 2개의 항목으로 처리됩니다.

배열에 추가된 명령 결과를 찾기 위해 반복하시겠습니까? 공백이 포함된 파일 이름은 2개의 항목으로 처리됩니다.

다음 코드를 만들었습니다. 마지막으로 배열의 각 파일을 개별적으로 처리하고 싶지만 이 코드 어딘가에는 큰따옴표를 포함하지 않으므로 중간에 공백이 있는 파일 이름은 배열에서 2개의 항목으로 처리됩니다.

#!/bin/bash

EXT=(sh mkv txt)

EXT_OPTS=()
# Now build the find command from the array
for i in "${EXT[@]}"; do
    EXT_OPTS+=( -o -iname "*.$i" )
done

# remove the first thing in EXT_OPTS
EXT_OPTS=( "${EXT_OPTS[@]:1}" )

# Modify to add things to ignore:
EXT_OPTS=( '(' "${EXT_OPTS[@]}" ')' ! '(' -iname "*test*" -o -iname "*sample*" ')' )

#echo "${EXT_OPTS[@]}"

searchResults=($(find . -type f "${EXT_OPTS[@]}"))

#echo "$searchResults"

for R in "${searchResults[@]}"; do
    echo "$R"
    sleep 1
done

그래서 내가 얻는 결과는 다음과 같습니다.

./Find2.sh
./untitled
2.sh
./countFiles.sh
./unrar.sh
./untitled
3.sh
./untitled
4.sh
./clearRAM.sh
./bash_test.sh
./Test_Log.txt
./untitled.txt
./Find.txt
./findTestscript.sh
./untitled.sh
./unrarTest.sh
./Test.sh
./Find.sh
./Test_Log
copy.txt
./untitled
5.sh
./IF2.sh

예를 들어 Untitled5.sh는 2개의 항목으로 배열에 추가되었습니다. "s를 추가하는 것을 어디에 잊었나요?

건배

제안된 수정사항:

#!/bin/bash

EXT=(sh mkv txt)

EXT_OPTS=()
# Now build the find command from the array
for i in "${EXT[@]}"; do
    EXT_OPTS+=( -o -iname "*.$i" )
done

# remove the first thing in EXT_OPTS
EXT_OPTS=( "${EXT_OPTS[@]:1}" )

# Modify to add things to ignore:
#EXT_OPTS=( "${EXT_OPTS[@]:-1}" )
EXT_OPTS=( '(' "${EXT_OPTS[@]}" ')' ! '(' -iname "*x0r*" -o -iname "*torrent*" ')' )

#echo "${EXT_OPTS[@]}"

#searchResults=($(find . -type f "${EXT_OPTS[@]}"))

#echo "$searchResults"

#for R in "${searchResults[@]}"; do
#   echo "$R"
#   sleep 1
#done


find . -type f "${EXT_OPTS[@]}" -exec sh -c '
    for pathname do
        printf "%s\n" "$pathname"
        sleep 1
    done' sh {} +

현재 생산 중:

./Find2.sh
./untitled 2.sh
./countFiles.sh
./unrar.sh
./untitled 3.sh
./Find3.sh
./untitled 4.sh
./clearRAM.sh
./bash_test.sh
./Test_Log.txt
./untitled.txt
./Find.txt
./findTestscript.sh
./untitled.sh
./unrarTest.sh
./Test.sh
./Find.sh
./Test_Log copy.txt
./untitled 5.sh
./IF2.sh
./Find4.sh

답변1

아니요, 출력을 구문 분석하면 안 됩니다 find. 찾은 경로 이름으로 작업을 수행 하려면 find다음 내에서 수행해야 합니다 find.

find ...stuff... -exec sh -c '
    for pathname do
        printf "%s\n" "$pathname"
        sleep 1
    done' sh {} +

여기서는 find일괄적으로 발견된 경로 이름을 사용하여 인라인 쉘 스크립트가 호출됩니다(스크립트는 여러 번 호출될 수 있음). find내부 스크립트의 경로 이름 생성기 역할을 합니다.

또 다른 접근 방식은 출력에 중간 경로 이름을 사용한 -print0다음 null로 끝나는 경로 이름을 읽는 방법을 아는 도구를 사용하여 읽는 것입니다. \0nul 문자 \0는 Unix 경로 이름의 일부가 될 수 없는 유일한 문자이므로 이 문자를 다른 도구에 전달하는 유일한 안전한 방법입니다.

관련된:

답변2

최신 버전 bash(>4.4 IIRC) 의 경우 mapfile내장을 통해 null 구분 기호를 지정할 수 있습니다. 그런 다음 find ... print0제안된 대로 사용할 수 있습니다.코살로난다의 답변예를 들어

mapfile -t -d '' searchResults < <(find . -type f "${EXT_OPTS[@]}" -print0)

이것이 옵션이 아닌 경우 더 느리고 추악한 접근 방식은 다음과 같습니다.

while IFS= read -r -d '' f; do 
  searchResults+=("$f")
done < <(find . -type f "${EXT_OPTS[@]}" -print0)

관련 콘텐츠 보기bash: 공백 안전 절차 사용을 선택하려면 찾기

관련 정보