Bash
用迭代值替換大文件中的計數器欄位
我有一個巨大的文本文件,裡面有大約 70k 行。我的目標是讀取這個文件,匹配一個模式(“計數”),並用一個迭代數字添加或替換它的值。
我正在做的是:
- 讀取文件。
- Grep 為模式計數。
- 如果匹配,則刪除該模式。
- 在該行中附加 filw 所需的模式 (Count = $i)。
- 遞增變數 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
值(輸入行)並使用單個最後一個變體可以縮短為
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 =