这个伟大的社区给了我下面的脚本来对信息行进行排序。
开始 {
FS=":"
PROCINFO["sorted_in"]="@val_str_asc";
}/./ {
值[$1]=$0
}/^$/ {
asort(values)
for (values 中的元素)
打印值[element]
print ""
删除值
}结尾 {
asort(值)
for (值中的元素)
打印值[元素]
}
每个块都按字母顺序排序,这按最初的预期工作(如下所示)。现在要求我根据 sessionStartTime 对所有这些数据块(每个数据块之间都有物理空间)进行排序。我认为这会困难得多,因为每个 8 行块都需要粘在一起。
cabLoginID:0557CAWG0FP27K31JG7Q
登录名:john
memoryInfo:jsHeapSizeLimit:2181038080
会话:cabSessionID:05P2R3PJGKG2Y2XE4NCZ
会话开始时间:2018-10-18T13:03:00.973Z
总JSHeapSize:36675584
使用JSHeapSize:29721040
userAgent:Mozilla/5.0cabLoginID:05P4X6K6GFPJ7K31EJ7H
登录名:bob
内存信息:jsHeapSizeLimit:2181038080
会话:cabSessionID:0536XLJPG7BJXRN42A0F
会话开始时间:2018-10-11T11:37:28.195Z
总JSHeapSize:54501376
使用JSHeapSize:35478968
userAgent:Mozilla/5.0cabLoginID:053XCDTF8D4J6PD3BG8P
登录名:jack
memoryInfo:jsHeapSizeLimit:2217857988
会话:cabSessionID:052FPBP6Q6X2XGERWHBT
会话开始时间:2018-10-01T01:04:10.899Z
总JSHeapSize:42358792
使用JSHeapSize:36482584
userAgent:Mozilla/5.0
期望的结果:
cabLoginID:053XCDTF8D4J6PD3BG8P
登录名:jack
memoryInfo:jsHeapSizeLimit:2217857988
会话:cabSessionID:052FPBP6Q6X2XGERWHBT
会话开始时间:2018-10-01T01:04:10.899Z
总JSHeapSize:42358792
使用JSHeapSize:36482584
userAgent:Mozilla/5.0cabLoginID:05P4X6K6GFPJ7K31EJ7H
登录名:bob
内存信息:jsHeapSizeLimit:2181038080
会话:cabSessionID:0536XLJPG7BJXRN42A0F
会话开始时间:2018-10-11T11:37:28.195Z
总JSHeapSize:54501376
使用JSHeapSize:35478968
userAgent:Mozilla/5.0cabLoginID:0557CAWG0FP27K31JG7Q
登录名:john
memoryInfo:jsHeapSizeLimit:2181038080
会话:cabSessionID:05P2R3PJGKG2Y2XE4NCZ
会话开始时间:2018-10-18T13:03:00.973Z
总JSHeapSize:36675584
使用JSHeapSize:29721040
userAgent:Mozilla/5.0
答案1
假设时间戳在您的语言环境中按词法排序,并给出 GNU Awk 版本 4.0 或更高版本:
gawk -vRS= '
match($0,/sessionStartTime:([^[:space:]]*)/,m) {
a[m[1]] = $0
}
END {
PROCINFO["sorted_in"] = "@ind_str_asc"
for (i in a) print a[i] "\n"
}' file
Perl 中的类似方法:
perl -00 -lne '
$h{$1} = $_ if /sessionStartTime:(\S*)/
}{
for $k (sort keys %h) {print $h{$k}}
' file
答案2
这似乎可以解决问题。我很快就会尝试发布一个更具可读性的版本。
$ perl -e 'while(<>){next if /^$/;push @a,$_;if(/sessionStartTime/){$k=$_}if($#a==7){$v{$k}=[@a];undef @a}}for $x(sort keys %v){for $i (0..7){print $v{$x}[$i]}print "\n"}' <input >output
更干净、更具可读性的版本。功能相同。
perl -e 'while(<>) {
# skip any blank lines
next if /^$/;
# add line to array a
push @a,$_;
# if line holds our key value, store it
if(/sessionStartTime/) {
$k=$_;
}
# if we've got all 8 lines, store it in a hash, keyed on our sessionStartTime
if($#a==7) {
$v{$k}=[@a];
undef @a;
}
}
# After reaching end of file, process each key and print its 8 lines
for $x (sort keys %v) {
for $i (0..7) {
print $v{$x}[$i];
}
print "\n";
}' <input >output
答案3
在bash中:
declare -a LINES
declare -A BLOCKS
IFS=$'\n'
addToBlocks() {
if [ "$EPOCH" ]
then
BLOCKS["$EPOCH"]="${LINES[*]}"
else
echo "No sessionStartTime line for this block."
fi
}
while read LINE
do
SSTIME="${LINE/sessionStartTime:}"
[ "${SSTIME}" != "$LINE" ] && EPOCH="$( date +%s -d "${SSTIME%Z}" )"
if [ "${LINE// }" == "" ]
then
addToBlocks
LINES=()
EPOCH=""
else
LINES+=("${LINE}")
fi
done
addToBlocks
for TIME in $( echo "${!BLOCKS[*]}" | sort -n )
do
echo "${BLOCKS[$TIME]}"
echo
done
相同的基本想法 - 遍历行直到到达空白行,此时将其保存在由日期时间键入的哈希中。一旦所有行都被消耗,输出按哈希键排序的所有块。