Text-Processing
更改多個文本文件中單個行號上的文本
假設我有十個 bash shell 腳本:
script1.sh
,script2.sh
, …,script10.sh
. 最初,所有十個文件都是相同的。現在,我想在每個腳本中進行兩項更改:
- 在每個文件中,我想更改一個特定的行(比如第 8 行)——也就是說,刪除第 8 行中的所有內容並將其替換為我指定的*“常量”*字元串,例如
"This is line 8."
This is similar to this question,但是他們想用 替換"AAA"
,"BBB"
而我想用 替換第 8 行(不管它是什麼)"This is line 8."
。- 在每個文件中,我想更改另一個特定行(例如第 21 行)並將其替換為我指定的*“變數”字元串。例如,在
script1.sh
我想將第 21 行更改為"XYZ"
; 在script2.sh
我想將第 21 行更改為"PQR"
; 在script3.sh
我想將第 21 行更改為"ABC"
. 本質上,這只是對上面*(1)中的函式的多次呼叫——除了我將在一個單獨的文件中而不是在所有文件中進行更改,並且我指定了十個不同的字元串而不僅僅是一個。所以要在這裡獲得(2),也許我會用不同的參數呼叫(1)**十次不同的時間。我對使用常用 Linux 程序(如
bash
、vi
、awk
、gawk
等)的解決方案感興趣。
for file in f1 f2; do sed -i '8s/^.*$/foo/' "$file" done
使用 awk
for file in script1.sh script2.sh script3.sh ... script10.sh; do temp=$(mktemp) awk ' BEGIN { line8 = "This is line 8" line21["script1.sh"] = "XYZ" line21["script2.sh"] = "PQR" line21["script3.sh"] = "ABC" # ... } FNR == 8 { print line8; next } FNR == 21 && FILENAME in line21 { print line21[FILENAME]; next } {print} ' "$file" > "$temp" && mv "$temp" "$file" done
或者,使用 bash 和 sed
# bash variables to store new values. requires bash v4 for the associative array line8="This is line 8" declare -A line21=( [script1.sh]="XYZ" [script2.sh]="PQR" [script3.sh]="ABC" # ... ) # then use sed for file in script1.sh script2.sh script3.sh ... script10.sh; do sed -i "8s/.*/$line8/; 21s/.*/${line21[$file]}/" "$file" done
使用 sed 解決方案,您必須小心新行不包含“/”字元,因為這會破壞
s///
命令。儘管您可以使用不同的分隔符,例如s|pattern|replacement|
(在這種情況下,遞歸應用相同的警告)
ed
也可以:for file in script1.sh script2.sh script3.sh ... script10.sh; do ed "$file" <<ED_COMMANDS 8d 8i $line8 . 21d 21i ${line21[$file]} . w q ED_COMMANDS done