簡體   English   中英

重置awk中的行號計數

[英]reset row number count in awk

我有這樣的文件

file.txt的

0   1   a
1   1   b
2   1   d
3   1   d
4   2   g
5   2   a
6   3   b
7   3   d
8   4   d
9   5   g
10   5   g
.
.
.

我想復位行號數為0的第一列$1時在第二列字段的值$2的變化,用awk或bash腳本。

結果

0   1   a
1   1   b
2   1   d
3   1   d
0   2   g
1   2   a
0   3   b
1   3   d
0   4   d
0   5   g
1   5   g
.
.
. 

只要你不介意一點多余的內存使用,並且第二列是排序的,我認為這是最有趣的:

awk '{$1=a[$2]+++0;print}' input.txt

這個awk單行程似乎對我有用:

[ghoti@pc ~]$ awk 'prev!=$2{first=0;prev=$2} {$1=first;first++} 1' input.txt
0 1 a
1 1 b
2 1 d
3 1 d
0 2 g
1 2 a
0 3 b
1 3 d
0 4 d
0 5 g
1 5 g

讓我們分解腳本,看看它的作用。

  • prev!=$2 {first=0;prev=$2} - 這就是重置你的計數器的原因。 由於prev的初始狀態為空,我們重置第一行輸入,這很好。
  • {$1=first;first++} - 對於每一行,設置第一個字段,然后增加我們用於設置第一個字段的變量。
  • 1 - 這是“打印線”的簡寫。 它實際上是一個總是求值為“true”的條件,當條件/語句對缺少一個語句時,該語句默認為“print”。

很基本,真的。

當然,一個問題是當你更改awk中任何字段的值時,它會使用設置的任何字段分隔符重寫該行,默認情況下它只是一個空格。 如果要調整此值,可以設置OFS變量:

[ghoti@pc ~]$ awk -vOFS="   " 'p!=$2{f=0;p=$2}{$1=f;f++}1' input.txt | head -2
0   1   a
1   1   b

鹽味。

純粹的解決方案:

file="/PATH/TO/YOUR/OWN/INPUT/FILE"

count=0
old_trigger=0

while read a b c; do
    if ((b == old_trigger)); then
        echo "$((count++)) $b $c"
    else
        count=0
        echo "$((count++)) $b $c"
        old_trigger=$b
    fi

done < "$file"

該解決方案(IMHO)具有使用可讀算法的優點。 我喜歡其他人給出的答案,但對初學者來說並不是那么全面。

注意

((...))是一個算術命令,如果表達式非零,則返回退出狀態0;如果表達式為零,則返回1。 如果需要副作用(賦值),也用作let的同義詞。 請參見http://mywiki.wooledge.org/ArithmeticExpression

Perl解決方案:

perl -naE '
    $dec  =  $F[0] if defined $old and $F[1] != $old;
    $F[0] -= $dec;
    $old  =  $F[1];
    say join "\t", @F[0,1,2];'

每次從第一列中減去$dec 當第二列更改(其先前值存儲在$old )時, $dec增加以將第一列再次設置為零。 第一行工作需要defined條件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM