我是 bash 的初學者,這是我的問題。我有一個像這樣的檔案:
Azzzezzzezzzezzz...
Bzzzezzzezzzezzz...
Czzzezzzezzzezzz...
我嘗試在腳本中編輯此檔案。ABC字母在所有檔案中都是唯一的,每行只有一個。
我想e用一個數字替換每一行的第一行:
1以 開頭A,2在以 a 開頭的行中B,3在以 a 開頭的行中C,
我想回圈這個以獲得這種型別的結果
Azzz1zzz5zzz1zzz...
Bzzz2zzz4zzz5zzz...
Czzz3zzz6zzz3zzz...
這里的所有數字都是 0 到 9 之間的隨機 int 變數。我真的需要先在回圈的第一個 exec 中替換 1、2、3,然后是 5、4、6,然后是 1、5、3,依此類推。
我試過這個
sed "0,/e/s/e/$1/;0,/e/s/e/$2/;0,/e/s/e/$3/" /tmp/myfile
但結果是這樣的(因為我沒有指定行)
Azzz1zzz2zzz3zzz...
Bzzzezzzezzzezzz...
Czzzezzzezzzezzz...
我注意到做sed -i "/A/ s/$/ezzz/" /tmp/myfile會添加ezzz在 A 行的末尾所以我嘗試了這個
sed -i "/A/ 0,/e/s/e/$1/;/B/ 0,/e/s/e/$2/;/C/ 0,/e/s/e/$3/" /tmp/myfile
但它失敗了
sed: -e expression #1, char 5: unknown command: `0'
我在這里迷路了。
我在一個變數(讓我們稱之為number_of_e_per_line)e中有一個或行A中的數量。BC
謝謝你為我花費的時間。
uj5u.com熱心網友回復:
只需s在匹配的行上應用命令A。
sed '
/^A/{ s/e/$1/; }
/^B/{ s/e/$2/; }
# or shorter
/^C/s/e/$3/
'
s默認情況下,命令替換第一次出現。例如,您可以s/s/$1/2替換第二次出現,s/e/$1/g(如“全域”)替換所有出現。
0,/e/指定行的范圍- 它從第一行過濾行,直到匹配的行/e/。
sed不是 Bash 的一部分。它是一種單獨的(粗略的)編程語言,是一種非常標準的命令。請參閱https://www.grymoire.com/Unix/Sed.html。
uj5u.com熱心網友回復:
繼續評論。sed除非您的所有檔案只能有 3 行,否則這里是一個糟糕的選擇。原因是sed處理每一行并且無法為'e'.
相反,包裝sed在腳本中并跟蹤替換使您可以處理任何檔案,無論行數如何。您只需回圈并一次處理一行,例如
#!/bin/bash
[ -z "$1" ] && { ## valiate one argument for filename provided
printf "error: filename argument required.\nusage: %s filename\n" "./$1" >&2
exit 1
}
[ -s "$1" ] || { ## validate file exists and non-empty
printf "error: file not found or empty '%s'.\n" "$1"
exit 1
}
declare -i n=1 ## occurrence counter initialized 1
## loop reading each line
while read -r line || [ -n "$line" ]; do
[[ $line =~ ^.*e.*$ ]] || continue ## line has 'e' or get next
sed "s/e/1/$n" <<< "$line" ## substitute the 'n' occurence of 'e'
((n )) ## increment counter
done < "$1"
您在每行末尾的資料檔案"..."表明您的檔案比發布的代碼段大。如果你有開頭的行'A' - 'Z',你不想寫 26 個單獨的/match/s/find/replace/替換。如果您有 3 到 26 個(或更多)之間的某個值,您不希望為sed遇到的每個新檔案重寫不同的運算式。
這就是為什么我說這sed是一個糟糕的選擇。你真的沒有辦法讓這個任務成為一個通用的任務sed。使用腳本的缺點是隨著您需要處理的記錄數量增加(由于效率超過 100000 條左右),它將成為一個糟糕的選擇
示例使用/輸出
使用 in 中的腳本和 in 中replace-e-incremental.sh的資料file,您將執行以下操作:
$ bash replace-e-incremental.sh file
Azzz1zzzezzzezzz...
Bzzzezzz1zzzezzz...
Czzzezzzezzz1zzz...
file就地修改
由于您在sed這里多次呼叫,您需要將檔案的輸出重定向到臨時檔案,然后通過用臨時檔案覆寫它來替換原始檔案,例如
$ bash replace-e-incremental.sh file > mytempfile && mv -f mytempfile file
$ cat file
Azzz1zzzezzzezzz...
Bzzzezzz1zzzezzz...
Czzzezzzezzz1zzz...
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/478760.html
標籤:重击
上一篇:bash如何處理決議錯誤?
