Bash에서 여러 줄 명령 출력을 구문 분석하는 방법은 무엇입니까?

Bash에서 여러 줄 명령 출력을 구문 분석하는 방법은 무엇입니까?

다음을 출력하는 명령이 있습니다.

Some text here
    1,3456: "Descr 1"
    2,7891: "Descr 2"
    3,0976: "Descr 3"

Some other random text here

첫 번째 열을 구문 분석하고 값을 어딘가에 저장하여 최종 사용자에게 옵션을 제공할 수 있는 bash 스크립트를 작성하고 싶습니다.

awk를 사용하여 첫 번째 열을 가져올 수 있지만 끝에 있는 임의의 텍스트("여기에 다른 임의의 텍스트가 있습니다") 때문에 awk 명령이 엉망이 됩니다.

이것이 내가 지금까지 가지고 있는 것입니다:

#!/bin/bash

VERSIONS=`/usr/libexec/somebin -V`

OPTIONS=$VERSIONS | awk -F'[,]' '{print $1}'

while read -r line; do
   echo "... $line ..."
done <<< $OPTIONS

그것이 하는 일은 인쇄하는 것뿐입니다:

Some text here
    1,3456: "Descr 1"
    2,7891: "Descr 2"
    3,0976: "Descr 3"

...  ...

하지만 인쇄하고 싶습니다.

1
2
3

답변1

파이프 전의 간단한 명령:

OPTIONS=$VERSIONS | awk -F'[,]' '{print $1}'

OPTIONS로 설정합니다 $VERSIONS. 실제 유틸리티 이름이 없으므로 명령은 단지 할당일 뿐이므로 출력이 생성되지 않습니다. 따라서 아무것도 파이프로 연결되지 않으므로 awk아무 awk작업도 수행되지 않습니다. (뭔가를 해도 안 된다 $OPTIONS.

설상가상으로 파이프는 이전과 이후의 명령이 하위 쉘에서 실행되도록 보장합니다. 따라서 OPTIONS복합 명령이 포함된 쉘에는 설정되지 않습니다.

나는 당신이 원하는 것이 다음과 같다고 생각합니다.

OPTIONS=$(/usr/libexec/somebin -V | cut -f1 -d,)

아니면 어쩌면

VERSIONS=$(/usr/libexec/somebin -V)
OPTIONS=$(echo "$VERSIONS" | cut -f1 -d,)

여기서 cut명령은 호출한 것과 동일한 작업을 수행합니다 awk.

그러나 awk 명령이나 awk 명령 모두 "특정 텍스트"가 포함된 행을 필터링하지 않으므로 다음과 같은 실제 필터가 필요할 수 있습니다.

VERSIONS=$(/usr/libexec/somebin -V | grep ,)
OPTIONS=$(echo "$VERSIONS" | cut -f1 -d,)

답변2

awk -F'[,]' '/^[ ]/{print $1}'

공백으로 시작하는 줄에서만 작동하며 공백이 없는 줄은 건너뜁니다. 또 다른 옵션은 쉼표가 포함된 줄을 찾거나 공백 대신 교묘한 탭을 사용하는 경우 다른 정규식을 찾는 것입니다.

답변3

bash만 사용하여 이 작업을 수행할 수 있습니다.

IFS=","; while read -r a b; do [[ $a =~ [0-9]+ ]] && echo $a; done < 1; unset IFS
1
2
3

관련 정보