sed 및 정규식을 사용하여 파일에서 데이터 추출

sed 및 정규식을 사용하여 파일에서 데이터 추출

BusyBox가 포함된 임베디드 Linux에서 실행되는 시스템이 있습니다. 다음 콘텐츠를 포함하는 YAML 구성 파일 "cfg.yaml"이 있습니다.

range:
    tcpportmin: 10000
    tcpportmax: 20000

파일에서 일부 값을 추출해야 합니다. 예를 들어, "tcpportmin" 매개변수의 값은 "10000"입니다. 저는 스크립트를 통해 이 작업을 수행합니다.

작은 "cfg.yaml" 파일에서 이 코드를 실행하면 모든 것이 잘 됩니다.

RANGE=`cat cfg.yaml`
TCP_PORT_MIN=`echo $RANGE | sed "s/.*tcpportmin: \([[:digit:]]*\).*/\1/"`
echo $TCP_PORT_MIN
# Output:
# 10000

그러나 실제 "cfg.yaml" 파일의 크기는 수백 킬로바이트이며, 이 경우 오류가 발생합니다.

/test.sh: line 211: echo: Argument list too long

동일한 sed 명령을 파일에 직접 적용하면 결과가 잘못됩니다.

TCP_PORT_MIN=`sed "s/.*tcpportmin: \([[:digit:]]*\).*/\1/" cfg.yaml`
echo $TCP_PORT_MIN
# Output:
# range: 10000 tcpportmax: 20000

한 줄에 여러 sed 명령을 사용하려고 하면 결과가 비어 있습니다.

TCP_PORT_MIN=`sed -e "s/.*tcpportmin: \([[:digit:]]*\).*/\1/" -e "s/.*\([[:digit:]]*\).*/\1/p" cfg.yaml`
echo $TCP_PORT_MIN
# Output:
# <Nothing>

참고로 내 시스템의 sed 명령에 대한 도움말 화면은 다음과 같습니다.

BusyBox v1.15.3 (2018-08-13 13:52:22 NOVT) multi-call binary

Usage: sed [-efinr] SED_CMD [FILE]...

Options:
        -e CMD  Add CMD to sed commands to be executed
        -f FILE Add FILE contents to sed commands to be executed
        -i      Edit files in-place
        -n      Suppress automatic printing of pattern space
        -r      Use extended regex syntax

If no -e or -f is given, the first non-option argument is taken as the sed
command to interpret. All remaining arguments are names of input files; if no
input files are specified, then the standard input is read. Source files
will not be modified unless -i option is given.

내 질문은 다음과 같습니다sed 명령을 사용하여 파일에서 값을 추출하는 방법은 무엇입니까?

답변1

단 하나의 행만 일치한다는 것을 알고 있다면 올바른 방법은 다음과 같습니다.

sed -n 's/ *tcpportmin: \([[:digit:]]*\).*/\1/p' cfg.yaml

-n플래그는 명시적인 sed 명령(예: )에 의해 트리거된 출력을 제외한 모든 출력을 억제합니다 p. 따라서 위의 sed는 교체된 행만 출력합니다.

출력을 변수에 저장할 수 있습니다

TCP_PORT_MIN=$(sed -n 's/ *tcpportmin: \([[:digit:]]*\).*/\1/p' cfg.yaml)

$()가독성과 중첩을 위해 백틱 대신 백틱을 사용해야 합니다 .

관련 정보