awk: 필드에서 문자열 추출 [닫기]

awk: 필드에서 문자열 추출 [닫기]

입력 필드는 파이프 기호로 구분됩니다.

CCCC|Sess C1|s1 DA=yy07:@##;/u/t/we
DDDDD|Sess C2|s4 DB=yy8:@##;/u/ba

마지막 필드 변경의 출력을 얻고 싶습니다(해당 필드에서 첫 번째 =와 : 사이의 내용만 추출)

예상되는 출력은 다음과 같습니다.

CCCC|Sess C1|yy07
DDDDD|Sess C2|yy8

답변1

표준은 awk스키마를 기반으로 필드에서 데이터를 추출하는 데 그리 좋지 않습니다. 일부 옵션은 다음과 같습니다.

  • split()지정된 구분 기호를 기준으로 텍스트를 배열로 분할합니다.
  • match()일치가 발생한 위치를 나타내는 설정 RSTART및 변수를 지정한 다음 일치하는 부분을 추출하는 데 사용됩니다.RLENGTHsubtr()

그래서 여기 있습니다:

awk -F'|' -v OFS='|' '
  split($3, a, /[=:]/) >= 2 {print $1, $2, a[2]}' < file.txt

=따라서 a 또는 in의 첫 번째 발생과 두 번째 발생 :사이의 부분이 반환됩니다 $3.

또는:

awk -F'|' -v OFS='|' '
  match($3, /=[^:]*/) {
    print $1, $2, substr($3, RSTART+1, RLENGTH-1)
  }' < file.txt

GNU에는 의 명령 기능을 소개하는 awk확장이 있습니다 :gensub()sedsawk

gawk -F'|' -v OFS='|' '
  $3 ~ /=/ {
    print $1, $2, gensub(/^[^=]*=([^:]*).*/, "\\1", 1, $3)
  }' < file.txt

=-s 가 아닌 숫자가 뒤에 오는 것을 찾아 :다음 부분을 추출합니다 =. 문제 gensub()는 교체가 성공했는지 쉽게 알 수 없으므로 먼저 $3포함 여부를 확인해야 한다는 것입니다 =.

그리고 sed:

sed -n 's/^\([^|]*|[^|]*|\)[^=|]*=\([^:|]*\).*/\1\2/p' < file.txt

그리고 perl:

perl -F'[|]' -lane 'print "$F[0]|$F[1]|$1" if $F[2] =~ /=([^:]*)/' < file.txt

답변2

나는 노력할 것이다

awk -F\|  'BEGIN {OFS="|";} 
   {col=index($3,":"); 
    equ=index($3,"=");
    $3=substr($3,equ+1,col-equ-1); 
    print ; }' se

어디

  • -F\||입력 구분 기호 로 사용하도록 awk에 지시
  • equ=index($3,"=");세 번째 필드에서 =의 인덱스를 가져옵니다.
  • $3=substr($3,equ+1,col-equ-1); 실제 교체를 해보세요

답변3

첫 번째는 필드 3의 첫 번째 6번째 문자를 제거하고, 두 번째는 콜론(포함) 뒤의 모든 문자를 제거합니다.

awk -F\| '{sub(/.{6}/,"",$3)sub(/:.*/,"")}1' OFS=\| file

관련 정보