일부 열 형식 데이터가 있는데 이를 더 형식화하고 싶습니다. 다음과 같습니다.
$ getStats | grep ESTABLISHED | column -t
all tcp 117.54.56.131:80 <- 10.42.100.211:63752 ESTABLISHED:ESTABLISHED
all tcp 10.42.120.201:63752 -> 219.224.67.112:31180 -> 137.51.59.141:80 ESTABLISHED:ESTABLISHED
all tcp 77.221.237.24:443 <- 10.42.100.117:59999 ESTABLISHED:ESTABLISHED
기본적으로 전화하기 전에 column -t
TCP 상태 "ESTABLISHED:ESTABLISHED"를 첫 번째와 세 번째 행으로 더 이동하여 두 번째 행에 올바르게 배치되도록 하고 싶습니다. 어떻게 해야 하나요? 여기서 awk와 printf를 사용하는 것은 약간 혼란스러워 보입니다. 기본적으로 모든 열을 정렬하고 마지막 열만 오른쪽 정렬하고 싶습니다.
답변1
편집 1:
한 가지 접근 방식은 다음과 같습니다.
getStats | grep ESTABLISHED | column -t | sed \
-e 's/\(<-\|->\)[ ]\+/\1 /g' \
-e 's/[ ]\+\([^ ]\+$\)/\t\1/' | column -t -s " "
^--- TAB
all tcp 117.54.56.131:80 <- 10.42.100.211:63752 ESTABLISHED:ESTABLISHED
all tcp 10.42.120.201:63752 -> 219.224.67.112:31180 -> 137.51.59.141:80 ESTABLISHED:ESTABLISHED
all tcp 77.221.237.24:443 <- 10.42.100.117:59999 ESTABLISHED:ESTABLISHED
먼저 column -t
공백 뒤의 모든 연속 공백을 제거한 다음 마지막 열을 분리하고 새로운 작업을 수행하십시오.<-
->
tab
column -t -s '<TAB>'
명령줄에 있는 경우: -s
" Ctrl+VTAB" (일명 tab
) as 선택적으로 공백을 탭으로 바꿀 column
수 있습니다 .tr
sed
작업으로 설정 하고 건너뛰기 grep
및 기타 수정 사항:
getStats | column -t | \
sed '/ESTABLISHED/!d;s/\(<-\|->\) */\1 /g;s/ *\([^ ]*\)$/\t \1/' | \
column -t -s " "
^--- TAB
편집 2:
awk
헷갈 리시더라도 printf
옵션으로 남겨두겠습니다. 이 스크립트를 사용하면 다음과 같이 말할 수 있습니다.
getStats | scrip_name ESTABLISHED
유연한 맞춤 설정 등이 가능한 것도 장점 중 하나입니다.
어느 쪽이든 데이터를 두 번 구문 분석하거나 데이터에 대한 메타데이터를 저장하고 마지막에 인쇄합니다.
간단히 말해서, 이것이 하는 일은 다음과 같습니다:
- 각 열의 최대 너비를 기록합니다.
- 최대 열 수를 기록합니다.
- 각 필드를 행별로 배열에 저장합니다.
- 각 필드를 마지막에 인쇄하되 끝에 열의 최대 너비를 사용하십시오.
- 채우기최대 열 수 - 1공백이 있습니다.
- 마지막 필드를 인쇄합니다.
(코드와 나머지 코드 사이의 분할은 awk -v pat="$1" '
이 페이지의 사용자 정의 강조 표시 HTML 주석으로 인한 것입니다.)
#!/bin/bash
# Argument 1 is what to match against.
awk -v pat="$1" '
# Iff match pat.
$0 ~ pat {
# Highest number of columns.
if (NF > cols)
cols = NF
# Increment number of lines.
++nl
# Number of fileds on this line.
lines[nl] = NF
for (i = 1; i <= NF; ++i) {
# IFF not last field and
# width of field is > current width of column, store it in wc_a.
if (i < NF && (wc = length($i)) > wc_a[i])
wc_a[i] = wc
# Save columns in array lines[LINE COLUMN]=FIELD_DATA.
lines[nl,i] = $i
}
}
END {
# Loop lines.
for (i = 1; i <= nl; ++i) {
# Print all but last.
for (j = 1; j < lines[i]; ++j)
printf("%-*s ", wc_a[j], lines[i,j])
# Print "missing" columns.
for (; j < cols; ++j)
printf("%-*s ", wc_a[j], "")
# Print last column field.
printf("%s\n", lines[i,lines[i]])
}
}
' "$2"
# $2 is either file or empty: expect pipe.
오래된:
답변2
여기서 진짜 질문은열 수가 동일하지 않습니다.. 일부 행에는 6개의 열이 있고 일부 행에는 8개의 열이 있습니다.
따라서 해야 할 일은 누락된 x 및 y 필드에 빈 필드를 추가하는 것입니다(x 및 y는 5와 6 또는 3과 4일 수 있음).
다음을 수행할 수 있습니다.
F="\\(\\S\\S*\\)\\s*\\s"
# This is 0160, a nonbreaking space
G=" "
| sed -e "s/^$F$F$F$F$F$F*$/\\1 \\2 \\3 \\4 \\5 $G $G \\6/g" \
| column -t
sed
6개 필드만 있는 행을 식별하고 적절한 경우 2개 추가 필드를 추가합니다. 위와 같이 나는 얻는다.
all tcp 117.54.56.131:80 <- 10.42.100.211:63752 ESTABLISHED:ESTABLISHED
all tcp 10.42.120.201:63752 -> 219.224.67.112:31180 -> 137.51.59.141:80 ESTABLISHED:ESTABLISHED
all tcp 77.221.237.24:443 <- 10.42.100.117:59999 ESTABLISHED:ESTABLISHED
답변3
원하는 작업을 수행하는 Perl 스크립트는 다음과 같습니다.
$ getStats | grep ESTABLISHED | \
perl -ne '
chomp @a;
@a = split(" ",$_);
map { print "$_," } @a[0..4];
if ($a[5] !~ m/>/) {
map { print " , ,$_," } @a[5..$#a];
print "\n";
} else {
map { print "$_," } @a[5..$#a];
print "\n";
}
' | column -t -s ','
결과는 다음과 같습니다.
all tcp 117.54.56.131:80 <- 10.42.100.211:63752 ESTABLISHED:ESTABLISHED
all tcp 10.42.120.201:63752 -> 219.224.67.112:31180 -> 137.51.59.141:80 ESTABLISHED:ESTABLISHED
all tcp 77.221.237.24:443 <- 10.42.100.117:59999 ESTABLISHED:ESTABLISHED
나는 귀하의 접근 방식에 대해 약간 다른 접근 방식을 취하고 column -t
Perl 출력을 수정하여 각 필드 사이에 쉼표 ","를 도입했습니다. 따라서 `column 명령 이전의 출력은 다음과 같습니다.
all,tcp,117.54.56.131:80,<-,10.42.100.211:63752, , ,ESTABLISHED:ESTABLISHED,
all,tcp,10.42.120.201:63752,->,219.224.67.112:31180,->,137.51.59.141:80,ESTABLISHED:ESTABLISHED,
all,tcp,77.221.237.24:443,<-,10.42.100.117:59999, , ,ESTABLISHED:ESTABLISHED,
그런 다음 구분 기호에 대한 분할을 column -t -s ','
유도하는데 column
, 이는 단순한 공백보다 처리하기가 더 쉽습니다.
한 줄에 쉼표를 도입하는 것은 나에게는 다소 구식이지만 이 방법은 제 역할을 합니다. 더 단순화할 수도 있지만 실행 가능한 솔루션입니다.