문자열과 특수 문자를 "찾기" 사용하는 방법은 무엇입니까?

문자열과 특수 문자를 "찾기" 사용하는 방법은 무엇입니까?

일부 순차적 작업(일부 복사, 암호화, 업로드 및 간단한 논리 검사)을 수행하기 위해 (처음으로) bash 셸 스크립트를 작성하려고 하는데 find반환되는 문자열 때문에 어려움을 겪고 있습니다. 특수 문자 /\*)'("와 공백이 있습니다.

를 사용하여 이 문제를 해결하기 위한 제안을 보았지만 printf %q올바른 bash 구문을 찾을 수 없습니다.

다음은 문자열을 변경하는 방법에 대한 발췌입니다.

#!/bin/sh

find "/upload" -type f |
    while read -r path; do
        fixedpath=printf %q "$path"
        fixedpath=printf '%q' "$path"
        fixedpath=printf '%q' $path
        fixedpath=printf "%q" "$path"
        fixedpath="printf %q $path"
        fixedpath="printf '%q' $path"
        fixedpath=$(printf '%q' $path)
        echo $path >> list.txt
        echo $fixedpath >> list.txt
    done
exit 0

이 함수를 작성하는 6~12가지 다른 방법을 생각할 수 있지만 printf, 다른 명령에 매개변수로 전달할 수 있도록 유효한 경로를 반환하려면 어떤 방법을 사용해야 합니까?

우분투 16에서 작업 중입니다.

답변1

find특히 이상하고 멋진 파일 이름을 기대하는 경우 출력을 구문 분석하지 마십시오 .

대신 실행해야 하는 명령을 실행 -exec하거나 명령 자체에 스크립트를 삽입하면 됩니다 find.

find /upload -type f -exec sh -c '
    for pathname do
        printf "Would do something with \"%s\" here...\n" "$pathname"
    done' sh {} +

당연히 포함 스크립트를 자체 파일에 넣을 수도 있습니다.

#!/bin/sh

for pathname do
    printf 'Would do something with "%s" here...\n' "$pathname"
done

그런 다음...

find /upload -type f -exec /path/to/script.sh {} +

이 주제에 대한 추가 자료:

답변2

(아마도) 을 사용하면 #!/bin/sh대신 POSIX 사양을 사용하는 것으로 제한됩니다 bash. 언급했으므로 bashshebang을 #!/bin/bash.

바라보다이 페이지, 특히 "기타 예" 섹션을 참조하세요. 사용해야 하는 경우 제가 선호하는 방법 find은 다음과 같습니다.

#!/bin/bash

while IFS= read -r -d '' f; do
   echo "$f"
   # Other actions on "$f" here
done < <(find /upload -type f -print0)

exit

null 구분 기호를 사용하여 특수 문자를 안전하게 처리합니다.

또는 몇 가지 bash셸 옵션과 루프를 사용하는 것이 for더 간단합니다 .

shopt -s nullglob globstar

for f in /upload/**; do
   [[ -f $f ]] || continue
   echo "$f"
   # Other actions on "$f" here
done

두 가지 방법 모두에서 인용 해야 /upload합니다 ."$f"


답변3

*다음 줄을 실행하면 스크립트가 실패합니다(별표 확장).

echo $path
echo $fixedpath

예:

$ path='test *'
$ echo "$path"
test *

$ echo $path
test file 1 file2 A longer file in this directory Some_Other_file ......

해결책? : var 확장명을 인용하세요.

그렇긴 하지만, 작동하는 유일한 과제는 (인용하기도 함) 다음과 같습니다.

fixedpath=$(printf '%q' "$path")
echo "$path" >> list.txt
echo "$fixedpath" >> list.txt

그러나 find의 출력을 읽는 것은 나쁜 생각입니다. 변수를 인용하지 않는 것과 비슷한 방식으로 실패할 수 있습니다. 이 섹션에 대한 다른 답변을 읽어보세요. 모두 좋습니다.

관련 정보