두 패턴 사이의 값 추출

두 패턴 사이의 값 추출

Ubuntu를 사용하고 있는데 두 패턴 사이의 값을 추출하고 싶은데 필요한 문자열이 파일에 없습니다.

내 데이터는 다음과 같습니다.

[{"rows":[{"_uuid":["uuid","11111-222-33333-4444444"]}]}]

,나는 사이에 텍스트를 가져오고 싶습니다 . ]이는 내가 원한다는 것을 의미합니다 11111-222-33333-444444. 이 작업을 수행하려면 어떻게 해야 합니까 sed?

  1. 우분투제가 사용하고 있는 운영체제입니다.
  2. 어떤 파일이나 변수에도 저장되지 않습니다. 이것은 명령의 출력입니다. command1의 출력을 sed로 파이프하고 위 문자열을 구문 분석하여 필요한 정보만 얻으려고 합니다.
  3. 그것은에있다JSON체재. 이것이 우리가 얻는 유일한 데이터입니다 ...

답변1

사용하십시오 jq(입력이 컴팩트인지 여러 줄인지는 중요하지 않습니다).

your-command | jq -r '.[0].rows[0]._uuid[1]'

JSON 문서는 객체의 배열이며 이러한 최상위 객체 중 첫 번째 객체가 필요합니다 .[0]. 객체에는 rows배열이 포함되어 있으며 첫 번째 요소가 필요합니다 .rows[0]. 해당 요소의 이름을 딴 또 다른 배열이 있으며 _uuid해당 배열의 두 번째 요소가 필요합니다 ._uuid[1].

-r디코딩된 "원시" 데이터를 얻게 됩니다 . 그렇지 않은 경우 -r(따옴표로 묶인) JSON 문자열을 받게 됩니다.


데이터를 가져오는 완전히 다른 방법특별한JSON 문서를 가져옵니다.마지막 값파일에서:

your-command | jq -r 'getpath([paths(scalars)][-1])'

먼저 전체 문서에서 모든 스칼라 값을 생성하는 모든 "경로"를 사용 paths하고 마지막 값을 선택하세요. 그런 다음 표현식은 마지막 스칼라의 경로를 사용하여 getpath마지막 값을 추출합니다. 그러면 해당 문서에 대해 예상되는 출력이 생성됩니다.

다음 코드는 동일한 작업을 수행할 수 있지만 ..with의 명시적 재귀를 사용하여 select()모든 스칼라 값을 추출합니다.

your-command | jq -r '[.. | select(scalars)][-1]'

개인적으로 저는 이 답변에서 가장 중요한 제안을 선택하겠습니다. 왜냐하면 이 답변은 어떤 방식으로든 사용자에게 이해될 수 있는 문서의 구조를 사용하기 때문입니다. 관련된 배열 중 하나라도 더 많은 요소를 포함하기 시작하면 코드를 다시 검토하고 문제를 다시 표현해야 합니다.

답변2

만약 우리가 존재한다고 확신할 수 있다면언제나한 줄에 하나만 있으며 ,해당 줄과 그 뒤의 첫 번째 줄 ,사이의 모든 내용을 원하면 다음을 사용할 수 있습니다.]sed

 $ echo '[{"rows":[{"_uuid":["uuid","11111-222-33333-4444444"]}]}]' | sed 's/.*,\([^]]*\)\].*/\1/'
"11111-222-33333-4444444"

또는 따옴표도 피하십시오.

   $ echo '[{"rows":[{"_uuid":["uuid","11111-222-33333-4444444"]}]}]' | sed 's/.*,"\([^]]*\)"\].*/\1/'
11111-222-33333-4444444

sed그러나 이는 JSON 데이터처럼 보이므로 이 솔루션은 입력 형식을 조금만 변경해도 중단되므로 사용하면 안 됩니다 . 당신은해야전용 JSON 파서 사용대신에 좋아요 jq.

답변3

소중한 데이터에 숫자와 -만 포함되어 있는 경우 이 기능을 사용할 수 있습니다. (uuid가 23보다 길면 문제 없습니다.)

echo '[{"rows":[{"_uuid":["uuid","11111-222-33333-4444444"]}]}]' | sed  -n "s/.*,\"\([0-9-]\{23,\}\)\"].*/\1/p"

출력: 11111-222-33333-4444444

답변4

사용행복하다(이전 Perl_6)

~$ raku -MJSON::Tiny -e 'from-json($_)[0].<rows>[0].<_uuid>[1].put given slurp();'  file

위 내용은 Perl 계열의 프로그래밍 언어인 Raku로 작성된 답변입니다. 명령줄 플래그와 관련하여 raku --help쉘 명령줄을 호출하면 다음을 알 수 있습니다.

  • 이 플래그는 (아래) 기본적으로 활성화되어 -e있는 "한 줄짜리" 프로그램을 실행합니다 .strict

  • -M플래그는 "one-liner" 프로그램을 실행하기 전에 모듈을 로드합니다. 이 경우에는 JSON::Tiny.

입력 예:

[{"rows":[{"_uuid":["uuid","11111-222-33333-4444444"]}]}]

예제 출력:

11111-222-33333-4444444

모듈 홈페이지(아래 첫 번째, 두 번째 링크)에 따르면," JSON::Tiny배열과 객체뿐만 아니라 모든 값을 최상위 JSON 문자열로 허용한다는 점에서 ECMA-404의 상위 집합인 RFC7159를 구현합니다."from-jsonto-jsonOP의 입력은 및 모듈 기능을 사용하여 왕복될 수 있습니다.

이 Raku 답변, 특히 [0].<rows>[0].<_uuid>[1]하강 구조는 JSON탁월한 답변과 놀랍도록 유사합니다.첫 번째 jq@Kusalananda가 게시한 답변입니다.

https://raku.land/cpan:MORITZ/JSON::Tiny
https://github.com/moritz/json
https://raku.org

관련 정보