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 형식이었다면(데이터를 변환했을 수도 있습니다.)~에서대부분의 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

와 .grep​ 일치하는 데이터만 가져오고 요청된 필드와 값을 찾는 데 cut사용합니다 . 필드 구분자로 사용하여 에 입력 하고 두 번째 필드를 가져옵니다.grep -oocut=

$ 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

관련 정보