AWK: 줄의 패턴 위치에 관계없이 2개의 사용자 정의 필드 구분 기호 사이에서 패턴을 추출하는 방법은 무엇입니까?

AWK: 줄의 패턴 위치에 관계없이 2개의 사용자 정의 필드 구분 기호 사이에서 패턴을 추출하는 방법은 무엇입니까?

다음은 파일의 한 줄 조각입니다.

LN=FINE FOODS & PHARMACEUTICALS NTM, MIC=XAIM, RIC=FF.MI, SG=MA1

"MIC" 태그의 값을 추출하는 데 관심이 있습니다. 즉, 내가 원하는 출력은 다음과 같습니다.

XAIM

전체 코드 줄은 꽤 깁니다.

20200403: #379 IT0005215329 {CU=EUR, GTPID=144115188076657542, II=IT0005215329, IS=18814564, LN=FINE FOODS & PHARMACEUTICALS NTM, MIC=XAIM, RIC=FF.MI, SG=MA1, SN=801670, STY=ORDINARY, TK="0.0002 to 0.1,0.0005 to 0.2,0.001 to 0.5,0.002 to 1,0.005 to 2,0.01 to 5,0.02 to 10,0.05 to 20,0.1 to 50,0.2 to 100,0.5 to 200,1 to 500,2 to 1000,5 to 2000,10 to 5000,20 to 10000,50 to 20000,100 to 50000,200", TS=FF, TY=S, UQ=1}

라인에서 "MIC" 라벨의 ​​위치가 항상 동일하지는 않습니다.

나는 꽤 많은 튜토리얼을 읽었으며 모든 솔루션에는 사용자 정의 필드 구분 기호를 만든 다음 줄의 패턴 위치를 사용하여 원하는 패턴을 추출하는 것 같습니다.

예를 들어, 나는 다음에 주어진 예를 따르려고 노력했습니다.이 스레드, 즉 이 코드를 사용하여 "MIC" 태그에서 값을 추출합니다.

awk 'BEGIN {FS="MIC=|,"} {print $2}' input.txt

다음과 같은 결과가 나타납니다.

GTPID=144115188076657542

위에서 제공한 전체 줄 예제를 확인하면 출력은 "=" 기호가 있는 두 번째 태그 "GTPID"의 값입니다. 처음에 나는 이것이 {FS="MIC=|,"}"두 개의 사용자 정의 필드 구분 기호를 생성하는 것을 의미한다고 생각했습니다. 첫 번째는 MIC=이고 두 번째는 입니다 ,. 어떤 이유로 이 {print $2}두 필드 구분 기호 사이에 있는 내용이 인쇄될 것으로 예상했습니다.

그러나 위의 코드는 "=" 기호가 포함된 모든 패턴의 값을 인쇄하는 것으로 보입니다. 이 기호는 해당 줄의 두 번째 기호입니다.

그 사이의 MIC=값을 추출하는 방법은 무엇입니까 ,?

답변1

f[]데이터에 이름=값 쌍이 있을 때마다 먼저 해당 매핑( 아래)을 캡처하는 배열을 만든 다음 해당 이름으로 원하는 필드에 액세스할 수 있는 것이 좋습니다. 예를 들면 다음과 같습니다.

$ awk -F'[=,] *' '{for (i=1;i<NF;i+=2) f[$i]=$(i+1); print f["MIC"]}' file
XAIM

테스트 값을 조정하고 다른 필드를 임의의 순서로 인쇄하는 등의 작업이 얼마나 쉬운지 확인하세요.

awk -F'[=,] *' '
    { for (i=1;i<NF;i+=2) f[$i]=$(i+1) }
    (f["MIC"] == "XAIM") && (f["LN"] ~ /FOOD/){ print f["SG"], f["RIC"] }
' file
MA1 FF.MI

답변2

$ sed -n 's/.* MIC=\([^,}]*\).*/\1/p' file
XAIM

이는 문자열 을 sed일치 시키고 전체 줄을 해당 문자열로 바꾸는 데 사용됩니다 . 다른 모든 데이터는 삭제됩니다. MIC=SOMETHING,MIC=SOMETHING}SOMETHING


$ tr ',' '\n' <file | awk -F '=' '$1 == " MIC" { print $2 }'
XAIM

먼저 모든 쉼표를 줄 바꿈으로 바꾼 다음 문자를 필드 구분 기호로 awk사용하여 실행하십시오 =. 첫 번째 필드가 같으면  MIC두 번째 필드를 인쇄합니다.


$ awk -F ',' '{ for (i = 1; i <= NF; ++i) if (sub(" MIC=","",$i)) print $i }' file
XAIM

이는 awk입력만 받아 쉼표로 구분된 필드로 처리합니다. 모든 필드를 반복하고 필드가 string 으로 시작하면  MIC=해당 문자열이 필드에서 제거되고 나머지를 인쇄합니다.


파일이 JSON 형식인 경우(데이터를 변환한 것 같습니다.~에서JSON은 대부분의 REST API가 JSON 형식으로 데이터를 반환하고 해당 데이터가 금융 주식 시장과 관련이 있는 것으로 보이기 때문에 어느 시점에서는 JSON입니다.

{
  "CU": "EUR",
  "GTPID": 144115188076657540,
  "II": "IT0005215329",
  "IS": 18814564,
  "LN": "FINE FOODS & PHARMACEUTICALS NTM",
  "MIC": "XAIM",
  "RIC": "FF.MI",
  "SG": "MA1",
  "SN": 801670,
  "STY": "ORDINARY",
  "TK": "0.0002 to 0.1,0.0005 to 0.2,0.001 to 0.5,0.002 to 1,0.005 to 2,0.01 to 5,0.02 to 10,0.05 to 20,0.1 to 50,0.2 to 100,0.5 to 200,1 to 500,2 to 1000,5 to 2000,10 to 5000,20 to 10000,50 to 20000,100 to 50000,200",
  "TS": "FF",
  "TY": "S",
  "UQ": 1
}

그렇다면 jq가장 간단합니다.

$ jq -r '.MIC' file1
XAIM

답변3

AND grep및 .는 일치하는 데이터 cutgrep -o가져오고 o요청된 필드와 값을 찾는 데 사용됩니다. 이것을 필드 구분 기호로 입력 cut하고 두 번째 필드를 가져옵니다.=

$ grep -o 'MIC=[^,]*' input | cut -d= -f2
XAIM

그리고 sed. 일치하는 하위 패턴을 사용 ()하고 추출하여 요청된 필드/값 쌍을 찾습니다 \1.

$ sed -nE 's/^.*MIC=([^,]+).*$/\1/;p' input
XAIM
# or, alternatively,
$ sed -n 's/^.*MIC=\([^,]*\).*$/\1/;p' input
XAIM

그리고 awk. 필드 구분 기호와 레코드 구분 기호를 각각 =및 로 설정합니다 ,. 패턴이 일치하는 레코드의 경우 두 번째 필드(즉, 값)를 인쇄합니다.

$ awk 'BEGIN { FS="="; RS=","; } $1 ~ /MIC/ { print $2 }' input
XAIM

답변4

주문하다

 awk -F "," '{for(i=1;i<=NF;i++){if($i ~ /MIC/){gsub(/.*=/,"",$i);print $i}}}' 

파일 이름

산출

XAIM

관련 정보