Bash

用迭代值替換大文件中的計數器欄位

  • April 20, 2018

我有一個巨大的文本文件,裡面有大約 70k 行。我的目標是讀取這個文件,匹配一個模式(“計數”),並用一個迭代數字添加或替換它的值。

我正在做的是:

  1. 讀取文件。
  2. Grep 為模式計數。
  3. 如果匹配,則刪除該模式。
  4. 在該行中附加 filw 所需的模式 (Count = $i)。
  5. 遞增變數 i。

這是程式碼

line_count=0
i=0
while read line
do
       line_count=$((line_count+1))
       if echo "$line" | grep -q "Count"
       then
               sed -i "$line_count d" /tmp/$rand_file1
               sed -i "$line_count i Count = $i" /tmp/rand_file1
               i=$((i+1))
       fi
done </tmp/rand_file1

上述技術大約需要 25 分鐘才能完成。有沒有辦法減少這個時間,因為我將使用更大的數據文件?

以下是輸入模式和文件以及預期輸出:

輸入文件

Count
Name = Sarah
ID = 113
PhNo =

Count
Name = John
ID = 787
PhNo =

Count = 123
Name = Mike
ID = 445
PhNo =

Count Now
Name = Max
ID = 673
PhNo =

預期的輸出文件

Count = 1
Name = Sarah
ID = 113
PhNo =

Count = 2
Name = John
ID = 787
PhNo =

Count = 3
Name = Mike
ID = 445
PhNo =

Count = 4
Name = Max
ID = 673
PhNo =

在 shell 中解析文本文件非常慢並且極易出錯。您grep在輸入文件中每行執行一次,sed對於包含Count. 避免這樣做。

據我所知,這可能會被替換為

awk '$1 == "Count" { printf("Count = %d\n", ++i); next } { print }' rand_file1 >rand_file1.new

Count =這會在遇到第一個欄位恰好為 的行時輸出具有正確增量的行Count,並按原樣傳遞所有其他行。

或者,

awk '$1 == "Count" { $0 = sprintf("Count = %d", ++i) } { print }' rand_file1 >rand_file1.new

它修改$0值(輸入行)並使用單個print.

最後一個變體可以縮短為

awk '$1 == "Count" { $0 = sprintf("Count = %d", ++i) } 1' rand_file1 >rand_file1.new

另請參閱“為什麼使用 shell 循環處理文本被認為是不好的做法? ”。

簡短**awk**的方法:

awk '$1 == "Count"{ $0 = "Count = "++i }1' file

輸出:

Count = 1
Name = Sarah
ID = 113
PhNo =

Count = 2
Name = John
ID = 787
PhNo =

引用自:https://unix.stackexchange.com/questions/438011