![설명하다:](https://linux55.com/image/107445/%EC%84%A4%EB%AA%85%ED%95%98%EB%8B%A4%3A.png)
다음과 같은 파일이 있습니다.
S123456789^ABC|00||00||ZZ|MW00021C|ZZ|207RI0200X~LX|1~SV2|6666|FG>FG997|879.5|UN|4~DTP|472|D8|20150213~REF|6R|JHYU0003707988-1~LIN||N4|67202004164~LX|2~SV2|1234|FG>BP990|879.5|UN|12~DTP|472|D8|20170413~REF|6R|ABCD0003707988-1~LIN||N4|67202004908~
1
아래와 같이 다음 항목 LX
, 다음 FG997
항목을 추출한 다음 LIN||N4 옆에 있는 67202004164로 추출하고 다시 다음 항목으로 추출 하고 싶습니다 .SV2|****|HC> ,879.5
4
UN,20150213
DTP|472|D8
2
LX
UNIX를 사용하여 이를 달성하도록 도와줄 수 있는 사람이 있습니까?
이런 방식으로 구문 분석해야 하는 대용량 파일이 많이 있습니다.
답변1
파일의 모든 행이 동일한 구조를 갖는 경우 아래와 같이 awk를 사용할 수 있습니다.
$ awk -F"[|^~>]" -v OFS="," '{for (i=1;i<=NF;i++) print "Field",i,"---value:",$i}' <<<"$a"
#Output will be like:
Field,1,---value:,S123456789
Field,2,---value:,ABC
Field,3,---value:,00
Field,4,---value:,
Field,5,---value:,00
Field,6,---value:,
Field,7,---value:,ZZ
Field,8,---value:,MW00021C
Field,9,---value:,ZZ
Field,10,---value:,207RI0200X
Field,11,---value:,LX
Field,12,---value:,1
Field,13,---value:,SV2
Field,14,---value:,6666
Field,15,---value:,FG
Field,16,---value:,FG997
##More fields here - goes up to 51 ##
awk는 -F
구분 기호(입력 필드 구분 기호)를 정의하며 여러 문자일 수 있습니다.
위의 예에서는 chars |
, ^
, ~
를 >
구분 기호로 사용하여 awk가 행을 더 많은 부분으로 분할하도록 합니다.
더 많은 구분 기호를 추가하여 awk가 필드를 더 많은 부분으로 분할하도록 할 수 있습니다.
추신: 내 예의 변수 $a에는 질문 텍스트가 포함되어 있습니다.
원하는 필드를 식별했으므로 다음과 같은 스크립트를 작성하여 원하는 필드를 인쇄할 수 있습니다.
$ awk -F"[|^~>]" -v OFS="," '{print $1,$12,$16,etc}' <<<"$a"
OFS는 print가 필드를 인쇄하는 데 사용할 출력 구분 기호를 정의합니다.
awk에서 인쇄하는 경우 다음을 참고하세요.
* 이와 같은 내용을 인쇄할 때 '{print $1,$2}'
두 필드는 OFS(위 예에서는 쉼표)로 구분됩니다. --> field1,field2
* awk와 같은 내용을 인쇄하면 '{print $1 $2}'
두 필드가 인쇄됩니다. 필드는 연결됩니다 - 하나 차례로, 분리 없이 -->field1field2
답변2
이런 일은 쉽습니다 Perl
.
perl -lne '
BEGIN{ $SKIP = qr/(?:[^|]+[|])/; $, = ","; }
print map { s/[~].*[|]/,/; y/|/,/; s/,?$//r; }
/
^[^^]+
| (?: LX [|] ) \K \d+
| (?: SV2 [|] \d+ [|] FG[>] )\K $SKIP{2}
| (?: UN [|] ) \K \d+ $SKIP{3} \d+
| (?: LIN [|][|] $SKIP ) \K \d+
/xg;
' yourfile
설명하다:
-l
=> ORS=FS=\n
-n
=> dont print unless asked to
-e
=> 다음은 Perl
코드입니다. $,
=>OFS
BEGIN
block은 파이프로 구분된 필드를 건너뛰는 정규식을 정의합니다. 이 정규식은 파이프로 구분된 2개의 필드(때로는 3개까지)를 건너뛰어야 할 때 여러 번 발생하기 때문에 can
( box
대신 읽 습니다). ability
이렇게 하면 덜 무섭게 보입니다 regex
.
/.../xg는 모든 일치 항목의 목록(\K 오른쪽에 나타나는 항목만)을 반환하고 map { ... }는 일부 처리를 수행하고 결과를 표준 출력으로 인쇄합니다.
산출
S123456789,1,FG997,879.5,4,20150213,67202004164,2,BP990,879.5,12,20170413,67202004908