grep 명령의 출력을 bash 배열에 넣어보세요.

grep 명령의 출력을 bash 배열에 넣어보세요.

다음 grep 명령을 실행하면 예상한 결과가 나타납니다.

$ grep -o -E '/ |:|\\|<|>|\*|\?|\"| $' <<< '/home/ttwaro/temp/Test/This is a Test: Testing Number 1?/This is Test: Testing Number 1?.eng.srt'
:
?
:
?

하지만 출력을 배열에 넣으려고 하면 물음표 "?" 대신 문자 "C"가 표시됩니다. 내가 뭘 잘못했나요?

$ array=()
$ array+=($(grep -o -E '/ |:|\\|<|>|\*|\?|\"| $' <<< '/home/ttwaro/temp/Test/This is a Test: Testing Number 1?/This is Test: Testing Number 1?.eng.srt'))
$ printf '%s\n' "${array[@]}"
:
C
:
C

답변1

이런 일이 발생하는 이유는 C명령을 실행하는 디렉터리에 지정된 파일이나 하위 디렉터리가 있어서 ?이에 맞게 glob이 확장되기 때문입니다. 더 간단한 예를 들어 설명하자면 다음과 같습니다.

$ ls -la
total 92
drwxr-xr-x   2 terdon terdon 16384 Mar 26 18:53 .
drwxr-xr-x 170 terdon terdon 73728 Mar 26 13:57 ..

$ array=( $( printf '?\n' ) )
$ printf '%s\n' "${array[@]}"
?

이제 다음과 같은 파일을 만들고 C다시 시도합니다.

$ touch C
$ array=( $( printf '?\n' ) )
$ printf '%s\n' "${array[@]}"
C

작업 순서에 따라 다릅니다. 을 실행하면 array=( $( printf '?\n' ) )다음과 같은 일이 순서대로 발생합니다.

  1. 실행 되고 printf '?\n'를 반환합니다 ?.
  2. 이것인용되지 않음 ?쉘에 의해 일치하는 파일 이름으로 확장됩니다. 이 경우에는 C.
  3. 확장된 글로브는 배열의 요소 C로 저장됩니다 .0array

이를 방지하려면 와일드카드가 셸에서 보호되도록 배열 할당을 인용해야 합니다.

$ array=( "$( printf '?\n' )" )
$ printf '%s\n' "${array[@]}"
?

또는 원래 예를 사용하여 다음을 수행하십시오.

$ array=( "$(grep -o -E '/ |:|\\|<|>|\*|\?|\"| $' <<< '/home/ttwaro/temp/Test/This is a Test: Testing Number 1?/This is Test: Testing Number 1?.eng.srt')" )
$ printf '%s\n' "${array[@]}"
:
?
:
?

그러나 인용되었으므로 전체 결과가 단일 문자열로 나타나므로 배열에는 하나의 요소만 포함됩니다.

$ for ((i=0;i<${#array[@]}; i++)); do 
    printf 'element %s is %s\n' "$i" "${array[i]}"; 
done
element 0 is :
?
:
?

각 결과를 배열의 별도 요소로 얻으려면 아래 제안된 대로 다음과 같은 작업을 수행해야 합니다.고든 데이비슨댓글에서:

$ readarray -t array < <(grep -o -E '/ |:|\\|<|>|\*|\?|\"| $' <<< '/home/ttwaro/temp/Test/This is a Test: Testing Number 1?/This is Test: Testing Number 1?.eng.srt')

$ for ((i=0;i<${#array[@]}; i++)); do 
    printf 'element %s is %s\n' "$i" "${array[i]}"; 
done
element 0 is :
element 1 is ?
element 2 is :
element 3 is ?

grep이렇게 하면 셸이 출력을 볼 수 없으므로 인용할 필요가 없습니다.

마지막으로, 결과에 두 개의 s가 있는 이유는 C배열에 저장될 때 각 s가 a로 확장되기 때문입니다 ?.C

$ array=( ? ? ? )
$ printf '%s\n' "${array[@]}"
C
C
C

관련 정보