다음 코드를 만들었습니다. 마지막으로 배열의 각 파일을 개별적으로 처리하고 싶지만 이 코드 어딘가에는 큰따옴표를 포함하지 않으므로 중간에 공백이 있는 파일 이름은 배열에서 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로 끝나는 경로 이름을 읽는 방법을 아는 도구를 사용하여 읽는 것입니다. \0
nul 문자 \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: 공백 안전 절차 사용을 선택하려면 찾기