在bash中按特定顺序打印文件

在bash中按特定顺序打印文件,bash,shell,awk,sed,Bash,Shell,Awk,Sed,我有一个包含以下内容的文件: file.txt: Iteration 1 RAM: +456ms Cache: +142ms (total +417ms) Iteration 2 Spec: +152ms Cache: +149ms (total +413ms) Iteration 3 RAM: +184ms Spec: +172ms Searchms: +131ms (total +385ms) First launch 4 RAM: +149ms Searchms: +188ms 在

我有一个包含以下内容的文件:

file.txt:

Iteration 1
RAM: +456ms
Cache: +142ms (total +417ms)

Iteration 2
Spec: +152ms
Cache: +149ms (total +413ms)

Iteration 3
RAM: +184ms
Spec: +172ms
Searchms: +131ms (total +385ms)

First launch 4
RAM: +149ms
Searchms: +188ms
在每个
首次发布
之间的该文件中,内容可以不同,它不是固定的(例如:首次发布3包含三个元素,而首次发布2内容仅包含两个元素),因此任何数量的内容都可以在开始时未知的
首次发布
模式之间

预期产出:

RAM  456 184 149
Cache 142 149  
Spec 152 172
Searchms 131 188
由于不知道确切的方法,我尝试了这段代码

我的代码:

for i in {1..4}
do
awk "/First launch $i/{flag=1;next} /First launch $((i+1))/{flag=0} flag" file.txt> fl$i.txt
sed -i 's/\+//g' fl$i.txt
sed -i 's/://g' fl$i.txt
sed -i 's/(.*//g' fl$i.txt
sed -i 's/ms//g' fl$i.txt
awk '{print $1 "\t" $2}' fl$i.txt
done
我的输出有两个问题: 我正在为每个错误的模式生成文件。我还想在时间过后删除
ms
,但它也会从模式名称中删除
ms
(例如:Searchms to Search)

输出:

fl1.txt: 
    RAM     456
    Cache   142
fl2.txt : 
    Spec    152
    Cache   149
fl3.txt  :
    RAM     184
    Spec    152
    Search  131
fl4.txt : 
    RAM     149
    Search  188
请向我建议一种方法,在不生成任何额外文件的情况下获得预期输出,并在时间结束后删除
ms

一种使用awk的方法:

$ awk '
$1 !~ /^(|First)$/ {            # avoid forbidden keywords and empty lines
    gsub(/[^0-9]/,"",$2)        # remove non-numerals
    a[$1]=a[$1] OFS $2          # append to associative array 
}
END {                           # in the end
    for(i in a)                 # loop all keywords
        print i a[i]            # output
}' file
以awk默认顺序输出行(随机显示):

Perl一行程序:

$ perl -nE 'if (/^(\w+):\s+\+(\d+)ms/) { push @{$keys{$1}}, $2 } END { while (($k, $vs) = each %keys) { say join(" ", $k, @$vs) }}' file.txt
Spec 152 172
Searchms 131 188
Cache 142 149
RAM 456 184 149
(行的顺序将有所不同;若有必要,则将其输送至分拣)


工作原理:

对于文件中的每一行,如果它匹配正则表达式
^(\w+):\s++(\d)ms
(行的开头有1个或多个字母数字字符,后跟冒号、空格、加号、1个或多个数字,然后是字母m和s),它将数字添加到哈希中的相应数组中,并使用起始字作为键。然后它打印出所有这些起始词及其相关数组

基本上与awk答案的想法相同,但它使用字符串而不是数组,因为awk没有像perl那样的真正数组,只有关联数组(在perl行话中称为哈希)。

这可能适合您(GNU-sed):

除包含
的行以外的任何行都是噪声,请删除它们

除去每行中的键、空格和第一组整数以外的所有内容

将结果附加到保留空间

使用模式匹配,收集类似关键点的数据并保留在保留空间中

删除除最后一行以外的所有行

在文件末尾,切换到保留空间,删除引入的换行符并打印结果。

只需:

$ cat tst.awk
BEGIN { FS="[: ]+" }
/:/ { vals[$1] = vals[$1] OFS $2+0 }
END { for (key in vals) print key vals[key] }

$ awk -f tst.awk file
Cache 142 149
RAM 456 184 149
Searchms 131 188
Spec 152 172
#!/bin/bash
for i in RAM Cache Spec Searchms; do
    echo "$i `cat file.txt  | grep $i | grep -Eo '[0-9]{1,9}' | tr '\n' ' '`" >> out.txt
done
您可以更改第2行中的顺序(for循环)

输出:

$ cat out.txt 
RAM 456 184 149 
Cache 142 417 149 413 
Spec 152 172 
Searchms 131 385 188 

另一个Perl,使用段落模式-00

perl -00 -lnE ' 
               while(/(^\S+):.+?(\d+)/gm ) {push(@{$kv{$1}},$2)} 
            END { foreach(keys %kv) { print "$_ @{$kv{$_}}" } }    '
有投入

$ cat arya.txt
First launch 1
RAM: +456ms
Cache: +142ms (total +417ms)

First launch 2
Spec: +152ms
Cache: +149ms (total +413ms)

First launch 3
RAM: +184ms
Spec: +172ms
Searchms: +131ms (total +385ms)

First launch 4
RAM: +149ms
Searchms: +188ms

$ perl -00 -lnE ' while(/(^\S+):.+?(\d+)/gm ) {push(@{$kv{$1}},$2)} END { foreach(keys %kv) { print "$_ @{$kv{$_}}" } } ' arya.txt
RAM 456 184 149

Cache 142 149

Searchms 131 188

Spec 152 172


$

另外,
sed-isa/b/”文件;sed-i的s/c/d/'文件
最好表示为
sed-i-e的s/a/b/'-e的s/c/d/'文件
,它只在整个文件中循环一次。您真的想要这样吗?您正在丢失RAM和缓存(以及其他项)之间的相关性,我认为这应该是有用的?模式“First Launch”中的名称(例如:RAM、缓存等)在开始时是未知的,它可以是模式中的任何名称。我的意思是它不是硬编码的,它是动态的。更新以避免空记录和以
开头的记录。
。我不懂perl语言,如果答案是在bash中可能会更好。@Arya您可以在shell脚本中使用它。您能简要解释一下代码吗。这对我来说更容易理解。无论如何谢谢你@Arya添加了一个快速的解释。请添加一些这段代码正在做的事情,以及它如何帮助解决这个问题。@Selaron为什么?这是非常琐碎和非常清楚的-在阅读了awk文档后,您不理解其中的哪一部分?因为很有可能这会提高您的文章的质量:简洁是可以接受的,但更全面的解释更好。@Selaron不,不会。向此添加注释就像向代码
i++
添加
incrementing i
注释一样。请不要橡皮图章的“可能低质量”的标志,当一些自动化工具看到代码只回答,因为它提高了这个标志,为人谁了解该领域作出决定-如果你不知道该领域,那么不要评论,只是继续前进。我在低质量队列。“识别、改进或删除低质量帖子”通常不需要领域知识。对于只有源代码的答案,我自然倾向于留下评论。其余的由作者决定。我不是故意冒犯你的。
perl -00 -lnE ' 
               while(/(^\S+):.+?(\d+)/gm ) {push(@{$kv{$1}},$2)} 
            END { foreach(keys %kv) { print "$_ @{$kv{$_}}" } }    '
$ cat arya.txt
First launch 1
RAM: +456ms
Cache: +142ms (total +417ms)

First launch 2
Spec: +152ms
Cache: +149ms (total +413ms)

First launch 3
RAM: +184ms
Spec: +172ms
Searchms: +131ms (total +385ms)

First launch 4
RAM: +149ms
Searchms: +188ms

$ perl -00 -lnE ' while(/(^\S+):.+?(\d+)/gm ) {push(@{$kv{$1}},$2)} END { foreach(keys %kv) { print "$_ @{$kv{$_}}" } } ' arya.txt
RAM 456 184 149

Cache 142 149

Searchms 131 188

Spec 152 172


$