简体   繁体   English

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

[英]Print file in particular order in bash

I have file with content: 我有内容文件:

file.txt: 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

In this file between every First launch , content can be different, it is not fixed ( for example: First launch 3 contain three elements while First launch 2 contents only 2 elements), so any number of content can be between the First launch pattern which is not known at the beginning. 在每个First launch之间的这个文件中,内容可以不同,它不是固定的(例如:首先发布3包含三个元素,而First launch 2内容只有2个元素),所以任意数量的内容都可以在First launch模式之间在开始时不知道。

Expected Output: 预期产出:

RAM  456 184 149
Cache 142 149  
Spec 152 172
Searchms 131 188

Due to not knowing exact approach,I have tried this code. 由于不知道确切的方法,我尝试了这段代码。

My code: 我的代码:

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

My output has two issues: I am generating the file for each pattern which is wrong. 我的输出有两个问题:我为每个模式生成错误的文件。 Also I wanted to remove ms after the time but it also removes the ms from the pattern name (ex: Searchms to Search) 此外我想在时间之后删除ms ,但它也会从模式名称中删除ms (例如:Searchms to Search)

Output: 输出:

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

Please suggest me an approach to get the expected output without generating any extra file with the constraint of removing ms after the time. 请建议我一种方法来获得预期的输出,而不生成任何额外的文件,约束时间后删除ms

One using awk: 一个使用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

Output lines in awk default order (appears random): awk默认顺序的输出行(随机出现):

Cache: 142 149
Searchms: 131 188
Spec: 152 172
RAM: 456 184 149
$ 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

Perl one-liner: 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

(Order of the lines will vary; pipe it to sort if that matters) (线的顺序会有所不同;如果重要,请将其排序以进行排序)


How it works: 这个怎么运作:

For each line in the file, if it matches the regular expression ^(\\w+):\\s+\\+(\\d)ms (1 or more alphanumeric characters at the start of the line, followed by a colon, whitespace, a plus sign, 1 or more digits, and then the letters m and s), it adds the number to the appropriate array in a hash using the starting word as the key. 对于文件中的每一行,如果它与正则表达式^(\\w+):\\s+\\+(\\d)ms匹配^(\\w+):\\s+\\+(\\d)ms (行开头有1个或多个字母数字字符,后跟冒号,空格,加号符号,1个或多个数字,然后是字母m和s),它使用起始字作为键将数字添加到散列中的适当数组。 Then it prints out all those starting words and their associated arrays. 然后它打印出所有那些起始单词及其相关数组。

Basically the same idea as the awk answer, but that uses strings instead of arrays because awk doesn't have true arrays like perl, just associative ones (Which are called hashes in perl lingo). 与awk答案基本相同的想法,但是使用字符串而不是数组,因为awk没有像perl这样的真正数组,只有关联的数组(在perl术语中称为哈希)。

This might work for you (GNU sed): 这可能适合你(GNU sed):

sed -E '/:/!d;s/.([0-9]+).*/\1/;H;x;s/((\n\S+) \S+)(.*)\2(.*)/\1\4\3/;h;$!d;x;s/.//' file

Any lines other than those that contain a : are noise, so delete them. 比那些包含其他任何线路:有噪音,所以删除它们。

Remove all but the key, a space and the first set of integers from each line. 删除除了键,空格和每行的第一组整数之外的所有内容。

Append the result to the hold space. 将结果附加到保留空间。

Using pattern matching, gather up like keys data and retain in the hold space. 使用模式匹配,像键数据一样收集并保留在保留空间中。

Delete all but the last line. 删除除最后一行之外的所有行。

At the end of file, swap to the hold space, remove the introduced newline and print the result. 在文件末尾,交换到保留空间,删除引入的换行符并打印结果。

Another Perl, using paragraph mode -00 另一个Perl,使用段落模式-00

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

with inputs 有输入

$ 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


$

Simply: 只是:

#!/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

You can change the order in line 2 ( for loop ) 您可以更改第2行中的顺序(for loop)

Output: 输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM