다음 텍스트 줄을 특정 순서로 정렬하고 싶습니다. 제가 사용한 명령어는 sort
공백을 없애고 모든 줄을 공백으로 구분하지 않고 묶어서 알파벳순으로 정리하는 것이었습니다. 각 블록에는 8행의 데이터가 있습니다.
세션: cabSessionID: 052FPBP6Q6X2XGERWHBT
cabLoginID: 053XCDTF8D4J6PD3BG8P
로그인: jack
userAgent: Mozilla/5.0
sessionStartTime: 2018-10-01T01:04:10.899Z
메모리 정보: jsHeapSizeLimit: 2217857988
totalJSHeapSize 사용: 42358792
JHeapSize:36482584세션: cabSessionID: 052FPBP6Q6X2XGERWHJE
cabLoginID: 053XCDTF8D4J6PD3BG8P
로그인: jack
userAgent: Mozilla/5.0
sessionStartTime: 2018-10-01T01:16:41.558Z
메모리 정보: jsHeapSizeLimit: 2217857988
총 JSHeapSize: 17 775404 0
JSHeapSize 사용: 44842320메모리 정보: jsHeapSizeLimit: 2217857988
총 JSHeapSize: 45252608
JSHeapSize 사용: 24555080
세션: cabSessionID: 055S75T4QC8JYC4Q0456
cabLoginID: 053XCDTF8D4J6PD3BG8P
로그인: Frank
userAgent: 0
세션시작 시간:2018- 10-23T19:11:11.871Z
나는 최종 결과가 다음과 같기를 원합니다.
로그인: jack
cabLoginID: 053XCDTF8D4J6PD3BG8P
세션: cabSessionID: 052FPBP6Q6X2XGERWHBT
userAgent: Mozilla/5.0
sessionStartTime: 2018-10-01T01:04:10.899Z 메모리 정보: jsHeapSizeLimit: 2217857988
사용된
총 JSHeapSize : 42358792
JHeapSize: 36482584로그인: jack
cabLoginID: 053XCDTF8D4J6PD3BG8P
세션: cabSessionID: 052FPBP6Q6X2XGERWHJE
userAgent: Mozilla/5.0
sessionStartTime: 2018-10-01T01:16:41.558Z
메모리 정보: jsHeapSizeLimit: 2217857988
총 JSHeapSize: 17 775404 0
JSHeapSize 사용: 44842320로그인: fred
cabLoginID: 053XCDTF8D4J6PD3BG8P
세션: cabSessionID: 055S75T4QC8JYC4Q0456
userAgent: Mozilla/5.0
sessionStartTime: 2018-10-23T19:11:11.871Z
메모리 정보: jsHeapSizeLimit: 2217857988
총 JS 힙 크기: 4525 2608장
JSHeapSize 사용: 24555080
답변1
하드 코딩된 "순서"를 원하므로 awk가 연관 배열의 각 청크에 대한 데이터를 컴파일한 다음 원하는 순서대로 배열을 인쇄하도록 합니다.
스크립트 파일.awk
BEGIN {
FS=":"
}
/./ {
values[$1]=$0
}
/^$/ {
print values["loginName"]
print values["cabLoginID"]
print values["session"]
print values["userAgent"]
print values["sessionStartTime"]
print values["memoryInfo"]
print values["totalJSHeapSize"]
print values["usedJSHeapSize"]
print ""
delete values
}
END {
print values["loginName"]
print values["cabLoginID"]
print values["session"]
print values["userAgent"]
print values["sessionStartTime"]
print values["memoryInfo"]
print values["totalJSHeapSize"]
print values["usedJSHeapSize"]
}
그런 다음 다음을 실행하십시오.
awk -f scriptfile.awk < input
대안으로, 블록 라인의 순서는 신경 쓰지 않지만 여전히 일관된 순서를 유지하고 GNU awk가 있는 경우,
gnuscript.awk
BEGIN {
FS=":"
PROCINFO["sorted_in"]="@val_str_asc";
}
/./ {
values[$1]=$0
}
/^$/ {
asort(values)
for (element in values)
print values[element]
print ""
delete values
}
END {
asort(values)
for (element in values)
print values[element]
}
위 스크립트는 각 블록의 행을 알파벳 순서로 인쇄합니다.
cabLoginID:053XCDTF8D4J6PD3BG8P
loginName:jack
memoryInfo:jsHeapSizeLimit:2217857988
session:cabSessionID:052FPBP6Q6X2XGERWHBT
sessionStartTime:2018-10-01T01:04:10.899Z
totalJSHeapSize:42358792
usedJSHeapSize:36482584
userAgent:Mozilla/5.0
...
답변2
단락 모드에서 Perl을 사용하고 해싱을 사용하여 사용자 정의 정렬 순서를 정의할 수 있습니다.
perl -00 -F'\n' -ne '
our %rank;
BEGIN {
%rank = (
loginName => 1,
cabLoginID => 2,
session => 3,
userAgent => 4,
sessionStartTime => 5,
memoryInfo => 6,
totalJSHeapSize => 7,
usedJSHeapSize => 8
);
}
%h = ();
map { ($k,$v) = split(/:/, $_, 2); $h{$k} = $v } @F;
for $k (sort { $rank{$a} <=> $rank{$b} } keys %h) { print "$k:$h{$k}\n" };
print "\n";
' file
답변3
일련의 행을 동일한 방식으로 계속해서 정렬하려는 경우 이를 수행할 수 있는 간단한 한 줄 코드는 없다고 생각합니다.
당시 콜론으로 인해 awk가 모든 문자열을 캡처하지 못할까 봐 걱정되었기 때문에 이렇게 빠르고 간단한 쉘 스크립트를 작성했습니다. 실제로는 덩어리별로 정렬됩니다. 블록 내 순서는 printf에 의해 결정됩니다. 필요에 맞게 업데이트하세요.
#!/bin/bash
declare -A arr
(
while read l; do
if [[ "" == "${l}" ]]; then
printf "loginName:%s~cabLoginID:%s~session:%s~userAgent:%s~sessionStartTime:%s~memoryInfo:%s~totalJSHeapSize:%s~usedJSHeapSize:%s~\n" ${arr[loginName]} ${arr[cabLoginID]} ${arr[session]} ${arr[userAgent]} ${arr[sessionStartTime]} ${arr[memoryInfo]} ${arr[totalJSHeapSize]} ${arr[usedJSHeapSize]}
unset arr
declare -A arr
continue
fi
k=${l%%:*}
v=${l#*:}
arr[${k}]=${v}
done
printf "loginName:%s~cabLoginID:%s~session:%s~userAgent:%s~sessionStartTime:%s~memoryInfo:%s~totalJSHeapSize:%s~usedJSHeapSize:%s~\n" ${arr[loginName]} ${arr[cabLoginID]} ${arr[session]} ${arr[userAgent]} ${arr[sessionStartTime]} ${arr[memoryInfo]} ${arr[totalJSHeapSize]} ${arr[usedJSHeapSize]}
) | sort | tr '~' '\n'
exit 0
답변4
또한 시도
awk '
BEGIN {for (n=split("loginName cabLoginID session userAgent sessionStartTime memoryInfo totalJSHeapSize usedJSHeapSize", T); n; n--) FLSQ[T[n]] = n
}
{for (i=1; i<=NF; i++) {n = split ($i, T, ":")
OUT[FLSQ[T[1]]] = $i
}
for (i=1; i<=NF; i++) $i = OUT[i]
split ("", OUT)
}
1
' RS="" ORS="\n\n" FS="\n" OFS="\n" file
loginName:jack
cabLoginID:053XCDTF8D4J6PD3BG8P
session:cabSessionID:052FPBP6Q6X2XGERWHBT
userAgent:Mozilla/5.0
sessionStartTime:2018-10-01T01:04:10.899Z
memoryInfo:jsHeapSizeLimit:2217857988
totalJSHeapSize:42358792
usedJSHeapSize:36482584
.
.
.
이 BEGIN
섹션에서는 각 필드 레이블에 오름차순 숫자를 할당하여 각 레코드 출력의 필드 순서를 정의합니다. 여러 행의 레코드에서 작업할 때 태그를 배열로 분할하면 태그 번호로 색인이 지정된 전체 필드로 배열이 채워집니다 T
. OUT
레코드를 인쇄하기 전 마지막 작업은 전체 $0(= 레코드)를 재구성하는 것입니다. 모든 필드 및 레코드 구분 기호는 여러 줄의 레코드 레이아웃을 수용해야 합니다.