sourcecode

Bash 배열에 대한 명령어 출력 읽기

codebag 2023. 4. 23. 10:19
반응형

Bash 배열에 대한 명령어 출력 읽기

스크립트의 명령 출력을 어레이로 읽어야 합니다.명령어는 다음과 같습니다.

ps aux | grep | grep | x 

출력은 다음과 같이 행별로 표시됩니다.

10
20
30

명령어 출력의 값을 어레이로 읽고 어레이 크기가 3 미만일 경우 작업을 수행합니다.

공백이 되어 있는 경우(빈도가 높은 ), 또는 (예: 공백이 포함되어 있는 ), 또는 공백이 포함되어 있는 경우, .*,?,[...].

요소별로 1행씩 배열에서 명령어의 출력을 얻으려면 기본적으로 다음 3가지 방법이 있습니다.

  1. 4에서는 Bash 44 를 사용합니다.mapfile 효율적입니다 -가장 효율적입니다.

    mapfile -t my_array < <( my_command )
    
  2. 그 이외의 경우는, 출력을 읽어내는 루프(느리지만 안전):

    my_array=()
    while IFS= read -r line; do
        my_array+=( "$line" )
    done < <( my_command )
    
  3. Charles Duffy가 코멘트(고맙습니다!)에서 제시한 바와 같이, 다음 방법은 2번 루프 방식보다 더 나은 성능을 발휘할 수 있습니다.

    IFS=$'\n' read -r -d '' -a my_array < <( my_command && printf '\0' )
    

    이 양식을 정확히 사용하십시오. 즉, 다음 사항을 확인하십시오.

    • IFS=$'\n' 스테이트먼트와 같은 행에 있습니다.이것에 의해, 환경 변수만 설정됩니다.IFS 를 참조해 주세요.따라서 스크립트의 나머지 부분에는 전혀 영향을 주지 않습니다.이 변수의 목적은 다음과 같습니다.read 문자 EOL로 \n.
    • -r 이것은 중요합니다. 수 있다read 백슬래시를 이스케이프 시퀀스로 해석하지 않도록 합니다.
    • -d '' " " " " " .-d과 그 " " " "''를 하지 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」''Bash가 스테이트먼트를 해석할 때 인용 삭제 단계에서 사라지기 때문에, 는 표시되지 않습니다.이것이 말해준다read합니다.0바이트에서 읽기를 중지합니다..-d $'\0'을 사용하다 -d ''더 좋아요.
    • -a my_arrayreadmy_array개울을 읽으면서.
    • 하셔야 합니다.printf '\0'뒤의 진술 my_commandread0(반환코드(를 수 별 가 되지 않습니다.1set -e(어쨌든 하지 말아야 할 것) 단, 명심해 주십시오.을 사용하다은 ''와 '다르다'가 해 주세요.printf ''이치노 printf '\0' 바이트를 null로 필요합니다.read-d ''★★★★

가능한 경우, 즉, 코드가 Bash,4에서 실행된다고 확신하는 경우 첫 번째 방법을 사용합니다.더 짧다는 것도 알 수 있죠.

사용하고 싶은 경우read행이 읽힐 때 약간의 처리를 실행하는 경우 루프(루프 2)가 방법3보다 유리할 수 있습니다.루프에는 (를 통해) 직접 액세스 할 수 있습니다.$line(배열을 통해) 이미 읽은 행에 액세스할 수 있습니다.${my_array[@]}를 참조해 주세요).

주의:mapfile는 각 회선의 콜백 평가를 읽어내는 방법을 제공합니다.실제로 N 회선의 판독마다 콜백을 호출하도록 지시할 수도 있습니다.를 참조해 주십시오.help mapfile및 옵션-C그리고.-c그 안에 있습니다.(제 의견으로는 조금 투박하지만 간단한 작업만 있으면 가끔 사용할 수 있습니다.처음부터 왜 구현했는지도 잘 모르겠습니다!)


이제 다음 방법을 설명하겠습니다.

my_array=( $( my_command) )

공백이 있는 경우는, 다음과 같이 끊어집니다.

$ # I'm using this command to test:
$ echo "one two"; echo "three four"
one two
three four
$ # Now I'm going to use the broken method:
$ my_array=( $( echo "one two"; echo "three four" ) )
$ declare -p my_array
declare -a my_array='([0]="one" [1]="two" [2]="three" [3]="four")'
$ # As you can see, the fields are not the lines
$
$ # Now look at the correct method:
$ mapfile -t my_array < <(echo "one two"; echo "three four")
$ declare -p my_array
declare -a my_array='([0]="one two" [1]="three four")'
$ # Good!

그 후, 일부의 유저에게 추천할 것입니다.IFS=$'\n'★★★★

$ IFS=$'\n'
$ my_array=( $(echo "one two"; echo "three four") )
$ declare -p my_array
declare -a my_array='([0]="one two" [1]="three four")'
$ # It works!

이제 글로브를 사용하여 다른 명령을 사용합니다.

$ echo "* one two"; echo "[three four]"
* one two
[three four]
$ IFS=$'\n'
$ my_array=( $(echo "* one two"; echo "[three four]") )
$ declare -p my_array
declare -a my_array='([0]="* one two" [1]="t")'
$ # What?

냐면 called called라는 파일이 있기 때문입니다.t이 파일명은 글로벌과 일치합니다. [three four]이에서, 사람들은 …을 사용하는 것을 입니다.set -f무효로 : 당신은 가 있습니다.IFS를 사용합니다.set -f고장난 기술을 고칠 수 있다(실제로 고치지 않고 있다)그렇게 할 때 우리는 껍데기와 싸우는 이지 껍데기와 함께 일하는 것이 아닙니다.

$ mapfile -t my_array < <( echo "* one two"; echo "[three four]")
$ declare -p my_array
declare -a my_array='([0]="* one two" [1]="[three four]")'

우린 조개껍데기로 작업하고 있어!

사용할 수 있습니다.

my_array=( $(<command>) )

<command>my_array.

이 어레이의 길이에 액세스하려면

my_array_length=${#my_array[@]}

, 이제 되죠?my_array_length.

여기 간단한 예가 있습니다.(현재 폴더 아래에 있는) 파일과 디렉토리 이름을 배열에 배치하고 개수를 세는다고 가정합니다.대본은 다음과 같습니다.

my_array=( `ls` )
my_array_length=${#my_array[@]}
echo $my_array_length

또는 다음 스크립트를 추가하여 이 어레이를 반복할 수 있습니다.

for element in "${my_array[@]}"
do
   echo "${element}"
done

이것은 핵심 개념이며, 입력은 처리 전에 삭제해야 합니다(예: 추가 문자 삭제, 빈 문자열 처리 등).(이것은 이 스레드의 토픽에서 제외됩니다).

디렉토리 목록 전체를 현재 디렉토리에 복사하여 배열에 복사하는 경우 항상 도움이 됩니다.

bucketlist=($(ls))
#then print them one by one
for bucket in "${bucketlist[@]}"; do
echo " here is bucket: ${bucket}"
done

언급URL : https://stackoverflow.com/questions/11426529/reading-output-of-a-command-into-an-array-in-bash

반응형