簡體   English   中英

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

[英]Print file in particular order in bash

我有內容文件:

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

在每個First launch之間的這個文件中,內容可以不同,它不是固定的(例如:首先發布3包含三個元素,而First launch 2內容只有2個元素),所以任意數量的內容都可以在First launch模式之間在開始時不知道。

預期產出:

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默認順序的輸出行(隨機出現):

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單線:

$ 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匹配^(\\w+):\\s+\\+(\\d)ms (行開頭有1個或多個字母數字字符,后跟冒號,空格,加號符號,1個或多個數字,然后是字母m和s),它使用起始字作為鍵將數字添加到散列中的適當數組。 然后它打印出所有那些起始單詞及其相關數組。

與awk答案基本相同的想法,但是使用字符串而不是數組,因為awk沒有像perl這樣的真正數組,只有關聯的數組(在perl術語中稱為哈希)。

這可能適合你(GNU sed):

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

比那些包含其他任何線路:有噪音,所以刪除它們。

刪除除了鍵,空格和每行的第一組整數之外的所有內容。

將結果附加到保留空間。

使用模式匹配,像鍵數據一樣收集並保留在保留空間中。

刪除除最后一行之外的所有行。

在文件末尾,交換到保留空間,刪除引入的換行符並打印結果。

另一個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


$

只是:

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

輸出:

$ 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