列印文字檔案中跨行列數的頻率

列印文字檔案中跨行列數的頻率

我有一個文件看起來像:

1
2 4 5 6 
20
22
24 26 27 
29 30 31 32 34 40 50 56 58
234 235 270 500
1234 1235 1236 1237
2300

我想要一個輸出,顯示有 4 行 1 列,3 行 4 列,1 行 3 列,1 行 9 列。所以,輸出應該是:行(列)

4 (1)
1 (3)
3 (4)
1 (9)

考慮到我的真實數據很大,請問有什麼建議嗎?同時,我希望在輸出的最後一行中顯示最大列數(此處為 9),並在第一行中顯示最小列數。

答案1

如果您有最新 (> 4.0) 版本的 GNU awk:

gawk '
  {a[NF]++} 
  END {
    PROCINFO["sorted_in"]="@ind_num_asc"; 
    for (i in a) printf "%d (%d)\n", a[i], i;
  }' file
4 (1)
1 (3)
3 (4)
1 (9)

答案2

呆呆地方法(使用asorti函數):

awk '{a[NF]++}END{ asorti(a,b); for(i in b) printf("%d (%d)\n",a[b[i]],b[i]) }' file

輸出:

4 (1)
1 (3)
3 (4)
1 (9)

  • asorti(a,b)- 依索引對陣列進行排序

答案3

如果將表中的每個儲存格視為佔位符以建立所需的結果,則可以對重複行進行排序和計數,以確定有多少行具有相同數量的列。

a=$(sed 's/\([0-9]\+\)/1/g' file | sort | uniq -c)
dups=$( echo "$a" | cut -d' ' -f7 )

之後,您可以計算每行的單字數,以確定該行中有多少列。

words=$(echo "$a" | cut -d' ' -f8- | awk '{print NF}')
paste <(echo "$dups") <(echo "$words")
4       1
1       3
3       4
1       9

答案4

最簡單的版本是

cat data.txt | awk '{counts[NF] += 1} END { for (row_count in counts) { printf "%d (%d)\n", counts[row_count], row_count; }'

它只是使用NF變數來給出行中的字段數量並更新字典中與其關聯的相關值。然後在流的末尾,它只是迭代字典的所有鍵並以請求的格式列印它們。

相關內容