sed 또는 awk를 사용하여 텍스트 형식을 다시 지정하세요.

sed 또는 awk를 사용하여 텍스트 형식을 다시 지정하세요.

예를 들어 첫 번째 줄이 제목인 입력이 있습니다. 텍스트 형식을 아래 출력으로 다시 지정할 수 있습니까?

awk '{if ($2=="b" || $3 == "c" || $4 == "d" || $5 == "e" || $6 == "f" || $7 == "g" || $8 == "9" )'}' 

위의 시도가 작동하지 않습니다. 저는 Linux의 새로운 초보자입니다. 어떤 아이디어라도 크게 감사하겠습니다.

입력하다:

Name    Date          Time          Mxam     Mxterm
Maxus   Date:su,mo    Time:12,3:00  mxam:20  Mxterm:10
Feros   Time:12,3:00  Mxterm:19
Michel  Mxterm:16       

원하는 출력

Name    Date           Time              Mxam     Mxterm
Maxus   Date:su,mo     Time:12,3:00      mxam:20  Mxterm:10
Feros                  Time:12,3:00               Mxterm:19
Michel                                            Mxterm:16

답변1

GNUAWK:

awk -v IGNORECASE=1 '
FNR==1  {n = split($0, col)}
        {printf("%s ", $1); k=2
        for(i=2; i<=n; i++)
                printf("%s ", $0 ~ "\\<"col[i]"\\>"?$(k++):"")
        print ""}
' file | column -ts' '

IGNORECASE=1-패턴에서 대소문자 무시
column -ts' '-입력 구분 기호는 공백 문자로, 이는 awk의 프로그램을 크게 단순화합니다.

GNU SED:

sed -r '
s/\s+/ /g
1{h;b};G
:1;s/( \S*)(:\S*)(.*)\1/\3\1\2/i;t1
s/\n\S*//
:2;s/ [^: ]+( |$)/ \1/;t2
' file | column -ts' '

\n첫 번째 헤더 행이 구분 기호로 구분되어 각 행에 추가됩니다 . 첫 번째 열을 제외한 왼쪽의 열이 오른쪽의 해당 열을 대체합니다. 이 기호가 없는 나머지 :열은 공백으로 대체됩니다.

sed 스크립트 디버깅을 위한 팁:
-n플래그를 추가 sed -nr하고 l명령을 라인 3의 끝에 넣으십시오 - 1{h;b};G;l. 스크립트를 실행한 다음 4줄을 반복합니다. l명령 - 버퍼(패턴 공간)의 내용과 버퍼의 앵커 끝을 표시합니다.$

[awk 업데이트]:

awk '
NR==1   {n = split($0, col)}
        {k=1; for(i=1; i<=n; i++)
                printf( "%s ", $0 ~ "\\<"col[i]?$(k++):"")
        print ""}
' file | column -ts' '

초기 제목 일치에는 좋지만 전체 제목(예: insert_job days_somthing start_somting window term max_run_alarm must_somthing)을 작성하고 단어 끝 앵커를 사용하는 것이 더 좋습니다."\\<"col[i]"\\>"

첫 번째 열이 비어 있지 않고 고유한 이름을 식별자로 사용하는 경우 그대로 둘 수 있습니다.

awk '
NR==1   {n = split($0, col)}
        {printf("%s ", $1); k=2
        for(i=2; i<=n; i++)
                printf("%s ", $0 ~ "\\<"col[i]?$(k++):"")
        print ""}
' file | column -ts' '

col[]- 열 이름 col[1] == "Name"등 을 포함한 배열 col[2] == "Date"; - 단어 시작 앵커. 예 - 같음col[3] == "Time""\\<""\\<"col[2]"\\<Date"

삼항 연산자 -condition expression ? statement1 : statement2
조건식이 true를 반환하면 명령문1이 실행되고, 그렇지 않으면 명령문2가 실행됩니다.

$0 ~ "\\<"col[i]?$(k++):""- 따라서 현재 줄 $0에 가 포함되어 있으면 "\\<"col[2]다음 필드는 현재 줄(예 : ) $(k++)에 나타나는 순서대로 인쇄되고 , 그렇지 않으면 빈 필드가 인쇄됩니다 .$2$0""

[awk 업데이트2]: 후행 공백을 제거합니다.

awk '
NR==1   {n = split($0, col)}
        {printf("%s ", $1); k=2
        for(i=2; i<=n; i++)
            printf("%s%c", ($0~"\\<"col[i]?$(k++):""), (n>i?OFS:ORS))}
' file | column -ts' '

[awk update3]: 필드를 재정렬하는 데 사용됩니다.

awk '
NR==1   {n = split($0, col)}
        {k=1; for(i=1; i<=n; i++)
                A[i] = ($0~"\\<"col[i]?$(k++):"")
        for(i in A) $i = A[i]
        }
1' file | column -ts' '

답변2

데이터에 태그=값 쌍이 포함될 때마다(예: Date:su,mo태그 is Data및 값 is su,mo) 먼저 해당 매핑을 보관할 배열을 구성한 다음( tag2val[]아래) 이를 통해 액세스/인쇄하거나 이러한 값 레이블을 비교할 수 있습니다( 일명 이름) 원하는 순서대로. 이 예에서는 레이블이 첫 번째 입력 줄에 나타나는 순서대로 값을 인쇄하지만 이 접근 방식을 사용하면 더 많은 작업을 쉽게 수행할 수 있습니다.

$ cat tst.awk
BEGIN { OFS="\t" }
NR==1 {
    for (fldNr=1; fldNr<=NF; fldNr++) {
        val = $fldNr
        tag = tolower(val)
        tag2val[tag] = val
        tags[++numTags] = tag
    }
}
NR > 1 {
    tag2val[tags[1]] = $1
    for (fldNr=2; fldNr<=NF; fldNr++) {
        val = $fldNr
        tag = tolower(val)
        sub(/:.*/,"",tag)
        tag2val[tag] = val
    }
}
{
    for (tagNr=1; tagNr<=numTags; tagNr++) {
        tag = tags[tagNr]
        val = tag2val[tag]
        printf "%s%s", val, (tagNr<numTags ? OFS : ORS)
    }
    delete tag2val
}

$ awk -f tst.awk file | column -s$'\t' -t
Name    Date        Time          Mxam     Mxterm
Maxus   Date:su,mo  Time:12,3:00  mxam:20  Mxterm:10
Feros               Time:12,3:00           Mxterm:19
Michel                                     Mxterm:16

답변3

공간 시각화를 sed위한 솔루션 은 다음과 같습니다 .#

$ sed -E '1s/\s+/#/' file | \
  tr -s ' ' '#' | \
  sed -E '2,$s/#*(D[^#]*)*#*(T[^#]*)*#*(mx[^#]*)*#*(Mx[^#]*)*$/#\1#\2#\3#\4/' | \
  tr '#' ' ' |\
  column -nt
Name    Date        Time          Mxam     Mxterm
Maxus   Date:su,mo  Time:12,3:00  mxam:20  Mxterm:10
Feros               Time:12,3:00           Mxterm:19
Michel                                     Mxterm:16

답변4

이는 데이터 형식을 다시 지정하는 또 다른 방법입니다.

우리는 awk를 사용하여 유틸리티용 코드를 생성 tbl한 다음 이를 groff텍스트 프로세서로 파이프하여 데이터를 표로 작성합니다.

< file \
awk -v OFS='@' '
{ split($0, a) }
NR==1{
  for (idx in a) b[tolower(a[idx])]=idx
  print ".TS"; print "tab(", ");"
  for (i=1; i<=NF; i++)
    printf "%s%s", "l", (i<NF ? OFS : ".")
  $1 = ORS $1
}
NR>1{
  $0=""; $1=a[1]
  for (i=2; i in a; i++) $(b[tolower(substr(a[i],1,-1+index(a[i],":")))]) = a[i]
}1
END { print ".TE" }
' | tbl | groff -Tascii | grep .

산출:

Name     Date         Time           Mxam      Mxterm
Maxus    Date:su,mo   Time:12,3:00   mxam:20   Mxterm:10
Feros                 Time:12,3:00             Mxterm:19
Michel                                         Mxterm:16

관련 정보