.txt 파일에서 last_name을 인쇄하는 방법은 무엇입니까?

.txt 파일에서 last_name을 인쇄하는 방법은 무엇입니까?

내 Linux 컴퓨터에 다음 파일이 있습니다.

<names>
<first_name>Mohammed Sani</first_name>
<last_name>ABACHA</last_name>
<aliases>
<alias>ABACHE,Mohammed Sani</alias>
<alias>SANI,Mohammed</alias>
</aliases>
<low_quality_aliases>
<alias xsi:nil="true"/>
</low_quality_aliases>
<alternative_spelling xsi:nil="true"/>
</names>

다음 명령을 사용하여 이름을 인쇄하지만 이름만 인쇄합니다.

sed -n 's:.*<first_name>\(.*\)</first_name>.*:\1:p' 'test.xml' > name.txt

성을 추가하려면 어떻게 해야 하나요?

답변1

이름과 성 데이터가 같은 줄에 있고 그 사이에 탭이 있기를 원한다고 가정해 보겠습니다.

사용 xmlstarlet:

xmlstarlet sel -t -m '/names' \
    -v 'first_name' -nl \
    -v 'last_name' -nl file.xml 2>/dev/null |
paste - -

이 명령은 해당 노드와 그 아래 노드의 값을 파싱하여 xmlstarlet각각 한 줄씩 출력합니다.first_namelast_namenames

탭 문자를 구분 기호로 사용하여 출력의 두 줄을 한 줄에 붙여넣는 데 사용됩니다 paste. 예를 들어 with를 사용 -d ','하면 paste쉼표로 구분된 출력을 얻을 수 있습니다.

/dev/null나중에 문서에 xmlstarlet올바른 일부 가짜 네임스페이스 선언이 있기 때문에 표준 오류 스트림을 로 리디렉션합니다 .


xq다음에서 사용https://kislyuk.github.io/yq/:

xq -r '.names | [ .first_name, .last_name ] | @tsv' file.xml

이는 @tsv연산자를 사용하여 탭으로 구분된 출력을 생성합니다. 위의 코드와 동일한 데이터를 출력 xmlstarlet하지만 XPath 표현식 대신 표현식을 사용합니다 jq.

대신 전체 인용된 CSV 출력을 @tsv얻으세요 .@csv

답변2

두 번째 명령을 추가할 수 있습니다 s.

sed -n 's:.*<first_name>\(.*\)</first_name>.*:\1:p;s:.*<last_name>\(.*\)</last_name>.*:\1:p' 'test.xml' > name.txt

또는 확장 정규식을 사용하세요.

sed -En 's:.*<(first|last)_name>(.*)</\1_name>.*:\2:p' 'test.xml' > name.txt

업데이트: 두 이름을 같은 줄에 출력하도록 요청

동일한 줄에 출력을 넣으려면 다른 스크립트를 통해 공백이 있는 줄로 파이프하면 됩니다.

sed -En 's:.*<(first|last)_name>(.*)</\1_name>.*:\2:p' test.xml | sed 'H;1h;$!d;g;s/\n/ /g' > name.txt

패턴 공간의 모든 라인을 연결하는 데 사용됩니다 H,1h;$1d;g( H모든 라인을 예약된 공간에 추가하고, 1h이전 줄바꿈을 방지하기 위해 첫 번째 라인의 예약된 공간을 덮어쓰고, $!d마지막 라인을 제외한 모든 라인 처리를 중지하고, g예약된 공간 내용을 패턴 공간으로 이동). 그런 다음 s/\n/ /g모든 줄 바꿈을 공백으로 바꾸십시오. 귀하의 경우에는 g항상 두 줄만 있을 것이라고 확신한다면 이를 제거할 수 있습니다.

Linux에서는 GNU가 있고 동일한 결과를 sed얻을 수 있습니다.sed -z 's/\n/ /g'

보다 우아하게, 파일에서 여러 이름 쌍을 처리할 수 있으면 다음과 같은 작업도 수행할 수 있습니다.

sed -e '/.*<first_name>\(.*\)<\/first_name>.*/{s//\1/;h;}' -e '/.*<last_name>\(.*\)<\/last_name>.*/!d;s//\1/;H;g;s/\n/ /' 'test.xml' > name.txt

관련 정보