awk에서 원래 $0 구분 기호를 그대로 유지하면서 다양한 필드를 어떻게 인쇄합니까?

awk에서 원래 $0 구분 기호를 그대로 유지하면서 다양한 필드를 어떻게 인쇄합니까?

awk부분 문자열의 위치와 길이가 원본 $0의 필드 위치를 기준으로 하는 경우 $0의 부분 문자열을 추출하는 방법은 무엇입니까?

이는 첫 번째 항목을 제거하는 것과 사실상 동일합니다.선두필드와 마지막추적하다필드와 원래 $0으로 시작하는 모든 필드에 대한 선행 및 후행 구분 기호

예: 현재 범위는 US$4 ~ US$8(포함)이라는 것만 알고 있습니다.
구분 기호는 공백 및/또는 단일 쉼표입니다. " , "아니면 ","... 그리고 선행 구분 기호는 무시됩니다.

          Input: "   a  a  a   X marks   the   start,   Y   marks the  end  "
Expected Output: "X marks   the   start,     Y"

답변1

awk는 필드 위치나 구분 기호 문자열을 기억하지 않습니다. 필드 위치를 수동으로 찾아야 합니다. 별로 어렵지 않습니다.

echo "   a  b  c   X marks   the   start,   Y   marks the  end  " |
awk '{
    i=1; n=1; tmp=$0;  # i=field number, n=column number
    while (match(tmp, / *, *| +/)) {
        A[i]=n; B[i]=n+RSTART-1;     # A[i],B[i] = start,end of delimiter i
        ++i; n+=RSTART+RLENGTH-1;
        tmp=substr(tmp,RSTART+RLENGTH)
    }
    print substr($0, A[5], B[9]-A[5])   # start at 4+1 because the first field is empty
}'

답변2

구분 기호로 탭 문자가 없는 한 이는 해결책이 될 수 있습니다.

#!/usr/bin/awk -f

  {
    start = index($0, " " $4 " ")
    stop  = index($0, " " $8 " ")
    print substr($0, start+1, stop - start + length($8))
  }

답변3

현재로서는 선행 구분 기호가 있거나 없는 데이터에 대해 작동하지만 필드에 "정규식에 민감한" 데이터가 포함되어 있으면 실패합니다. 해결책은 각 필드를 정규식 점 .{필드 필드}...로 바꾸는 것입니다.이것은 링크입니다 이와 같은 버전에서는... 투박하지만 위의 문제와 충돌하지 않습니다.

awk 'BEGIN { FS = "([ \t]+)|([ \t]*,[ \t]*)" }
{ # Ignore leading delimiter, if present 
  hasLeadDlm = match($0, "^("FS")")
  LeadDlm = substr($0, 1, RLENGTH)
  if (hasLeadDlm) { sub("^("FS")", ""); }    # delete leading whitespace 
  sub("^"$1"("FS")"$2"("FS")"$3"("FS")", "") # delete leading fields
  match( $0, "^"$1"("FS")"$2"("FS")"$3"("FS")"$4"("FS")"$5)
  print substr($0, 1, RLENGTH)
}' <<< \
"a    X  a   X marks   the   start, ssY   marks the  end  
 a    X  a   X   marks the   start,  sY   marks the  end  
  a   X  a   X marks     the start,   Y   marks the  end  
   a  X  a   X marks   the     start ,Y   marks the  end  
    a   X  a   X marks   the   start,sssY   marks the  end"

관련 정보