[英]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.