하이퍼바이저에서 실행되는 가상 머신에 대한 세부 정보가 포함된 파일이 있습니다. 몇 가지 명령을 실행하고 출력을 파일로 리디렉션합니다. 데이터는 다음 형식일 수 있습니다.
Virtual Machine : OL6U5
ID : 0004fb00000600003da8ce6948c441bb
Status : Running
Memory : 65536
Uptime : 17835 Minutes
Server : MyOVS1.vmorld.com
Pool : HA-POOL
HA Mode: false
VCPU : 16
Type : Xen PVM
OS : Oracle Linux 6
Virtual Machine : OL6U6
ID : 0004fb00000600003da8ce6948c441bc
Status : Running
Memory : 65536
Uptime : 17565 Minutes
Server : MyOVS2.vmorld.com
Pool : NON-HA-POOL
HA Mode: false
VCPU : 16
Type : Xen PVM
OS : Oracle Linux 6
Virtual Machine : OL6U7
ID : 0004fb00000600003da8ce6948c441bd
Status : Running
Memory : 65536
Uptime : 17835 Minutes
Server : MyOVS1.vmorld.com
Pool : HA-POOL
HA Mode: false
VCPU : 16
Type : Xen PVM
OS : Oracle Linux 6
50개가 넘는 VM을 실행하는 일부 하이퍼바이저에서는 이 출력이 하이퍼바이저에 따라 다릅니다. 위 파일은 3개의 VM만 실행하는 하이퍼바이저의 예일 뿐이므로 리디렉션된 파일에는 여러(N개의 VM)에 대한 정보가 포함될 것으로 예상됩니다.
awk/sed 또는 쉘 스크립트를 사용하여 다음 형식으로 이 세부 정보를 가져와야 합니다.
Virtual_Machine ID Status Memory Uptime Server Pool HA VCPU Type OS
OL6U5 0004fb00000600003da8ce6948c441bb Running 65536 17835 MyOVS1.vmworld.com HA-POOL false 16 Xen PVM Oracle Linux 6
OL6U6 0004fb00000600003da8ce6948c441bc Running 65536 17565 MyOVS2.vmworld.com NON-HA-POOL false 16 Xen PVM Oracle Linux 6
OL6U5 0004fb00000600003da8ce6948c441bd Running 65536 17835 MyOVS1.vmworld.com HA-POOL false 16 Xen PVM Oracle Linux 6
답변1
당신이 가지고 있다면rs
(재발명) 유틸리티가능한 경우 다음을 수행할 수 있습니다.
rs -Tzc: < input.txt
이는 동적 열 너비까지 포함하여 질문에 지정된 것과 정확히 동일한 출력 형식을 제공합니다.
-T
입력 데이터 전치-z
각 열의 최대값을 기준으로 열 크기를 적절하게 조정합니다.-c:
입력 필드 구분 기호로 콜론 사용
이는 모든 크기의 테이블에 적용됩니다. 예를 들면 다음과 같습니다.
$ echo "Name:Alice:Bob:Carol
Age:12:34:56
Eyecolour:Brown:Black:Blue" | rs -Tzc:
Name Age Eyecolour
Alice 12 Brown
Bob 34 Black
Carol 56 Blue
$
rs
OS X(및 기타 BSD 시스템)에서 기본적으로 사용 가능합니다. 다음 명령을 사용하여 Ubuntu(및 debian 시리즈)에 설치할 수 있습니다.
sudo apt-get install rs
답변2
편집하다:간단한 한 줄 루프 for
에서 원하는 수의 출력 라인으로 확장 가능 :
for ((i=1;i<=2;i++)); do cut -d: -f "$i" input | paste -sd: ; done | column -t -s:
원래 답변:
프로세스 대체를 사용하여 이를 한 줄의 코드로 실행할 수 있습니다 bash
.
paste -sd: <(cut -d: -f1 input) <(cut -d: -f2 input) | column -t -s:
이 -s
옵션을 paste
사용하면 각 파일을 한 번에 처리합니다. :
세트 구분 기호는 paste
필드를 정렬하여 서식을 아름답게 만드는 마지막 옵션에 의해 "캡처"됩니다.-s
column
두 프로세스 대체의 명령은 cut
각각 첫 번째 필드와 두 번째 필드를 가져옵니다.
입력에 빈 줄이 있어도 상관없습니다. column -t -s:
어쨌든 출력이 삭제되기 때문입니다. (질문에 지정된 원래 입력에는 빈 줄이 있었지만 제거되었습니다. 위 명령은 빈 줄에 관계없이 작동합니다.)
입력 - 위 명령에서 "input"이라는 파일의 내용:
Virtual_Machine:OL6U7
ID:0004fb00000600003da8ce6948c441bd
Status:Running
Memory:65536
Uptime:17103
Server:MyOVS1.vmworld.com
Pool:HA-POOL
HA:false
VCPU:16
Type:Xen PVM
OS:Oracle Linux 6
산출:
Virtual_Machine ID Status Memory Uptime Server Pool HA VCPU Type OS
OL6U7 0004fb00000600003da8ce6948c441bd Running 65536 17103 MyOVS1.vmworld.com HA-POOL false 16 Xen PVM Oracle Linux 6
답변3
파일을 두 번 탐색하는 것이 (큰) 문제가 아닌 경우(한 행만 메모리에 저장됩니다):
awk -F : '{printf("%s\t ", $1)}' infile
echo
awk -F : '{printf("%s\t ", $2)}' infile
파일 경로가 많을 수 있는 일반적인 필드 수의 경우:
#!/bin/bash
rowcount=2
for (( i=1; i<=rowcount; i++ )); do
awk -v i="$i" -F : '{printf("%s\t ", $i)}' infile
echo
done
그러나 진정한 보편적 전치를 위해서는 다음이 작동합니다.
awk '$0!~/^$/{ i++;
split($0,arr,":");
for (j in arr) {
out[i,j]=arr[j];
if (maxr<j){ maxr=j} # max number of output rows.
}
}
END {
maxc=i # max number of output columns.
for (j=1; j<=maxr; j++) {
for (i=1; i<=maxc; i++) {
printf( "%s\t", out[i,j]) # out field separator.
}
printf( "%s\n","" )
}
}' infile
그리고 멋지게 만드십시오(탭을 \t
필드 구분자로 사용).
./script | |column -t -s $'\t'
Virtual_Machine ID Status Memory Uptime Server Pool HA VCPU Type OS
OL6U7 0004fb00000600003da8ce6948c441bd Running 65536 17103 MyOVS1.vmworld.com HA-POOL false 16 Xen PVM Oracle Linux 6
위의 일반 전치 코드는 전체 행렬을 메모리에 저장합니다.
이는 매우 큰 파일의 경우 문제가 될 수 있습니다.
새로운 텍스트로 업데이트하세요.
질문에 게시된 새 텍스트를 처리하려면 awk 두번이 가장 좋은 대답이라고 생각합니다. 패스는 필드가 존재하는 한 헤더 필드 제목을 인쇄합니다. 다음 awk 전달에서는 필드 2만 인쇄합니다. 두 경우 모두 선행 및 후행 공백을 제거하는 방법을 추가했습니다(더 나은 형식 지정을 위해).
#!/bin/bash
{
awk -F: 'BEGIN{ sl="Virtual Machine"}
$1~sl && head == 1 { head=0; exit 0}
$1~sl && head == 0 { head=1; }
head == 1 {
gsub(/^[ \t]+/,"",$1); # remove leading spaces
gsub(/[ \t]+$/,"",$1); # remove trailing spaces
printf( "%s\t", $1)
}
' infile
#echo
awk -F: 'BEGIN { sl="Virtual Machine"}
$1~sl { printf( "%s\n", "") }
{
gsub(/^[ \t]+/,"",$2); # remove leading spaces
gsub(/[ \t]+$/,"",$2); # remove trailing spaces
printf( "%s\t", $2)
}
' infile
echo
} | column -t -s "$(printf '%b' '\t')"
모든 것이 { ... } | column -t -s "$(printf '%b' '\t')"
전체 테이블의 형식을 좋은 방식으로 지정합니다.
이는 "$(printf '%b' '\t')"
ksh, bash 또는 zsh로 대체될 수 있습니다.$'\t'
답변4
awk를 사용하여 키와 값을 저장하고 최종적으로 인쇄합니다.
#!/usr/bin/awk -f
BEGIN {
CNT=0
FS=":"
}
{
HDR[CNT]=$1;
ENTRY[CNT]=$2;
CNT++;
}
END {
for (x = 0; x < CNT; x++)
printf "%s\t",HDR[x]
print""
for (x = 0; x < CNT; x++)
printf "%s\t",ENTRY[x]
}
그냥 도망갔어awk -f ./script.awk ./input.txt