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