我有一個包含很多 java 檔案的目錄,并且在每個檔案中我都有一個類變數:
String system = "x";
我希望能夠創建一個在同一目錄中執行的 bash 腳本,該腳本將只轉到目錄中的 java 檔案,并將x的這個實體替換為y。這里x和y是一個詞。現在這可能不是 java 腳本中單詞x的唯一實體,但它肯定是第一個。
我希望能夠在類似于以下的命令列中執行我的腳本:
changesystem.sh -x -y
這樣我可以指定x應該是什么,以及我希望用y替換它。我找到了一種方法來查找并列印找到模式的第一個實體的行號:
awk '$0 ~ /String system/ {print NR}' file
然后我找到了如何使用以下方法替換給定行上的子字串:
awk 'NR==line_number { sub("x", "y") }'
但是,我還沒有找到組合它們的方法。也許還有更簡單的方法?甚至,一種更好、更有效的方法?
任何幫助/建議將不勝感激
uj5u.com熱心網友回復:
您可以創建一個changesystem.sh檔案
#!/bin/bash
for f in *.java; do
awk -i inplace -v repl="$1" '!x && /^[[:space:]]*String[[:space:]] system[[:space:]]*=[[:space:]]*".*";[[:space:]]*$/{print " String system = \""repl"\";";x=1;next}1' "$f";
done;
或者,不使用-i inplaceGNU awk 功能:
#!/bin/bash
for f in *.java; do
awk -v repl="$1" '!x && /^[[:space:]]*String[[:space:]] system[[:space:]]*=[[:space:]]*".*";[[:space:]]*$/{print " String system = \""repl"\";";x=1;next}1' "$f" > tmp && mv tmp "$f";
done;
然后,使檔案可執行:
chmod x changesystem.sh
然后,像這樣運行它
./changesystem.sh 'new_value'
筆記:
for f in *.java; do ... done遍歷當前目錄中的所有 *.java 檔案-i inplace- GNU awk 功能來執行行內替換-v repl="$1"將腳本的第一個引數傳遞給awk命令!x && /^String system = ".*";$/- 如果x為假且記錄以String system = ", then 有任何文本并以";,結尾{print "String system = \""repl"\";";x=1;next}1- 列印String system = "替換字串";,分配1給x,然后移動到下一行,否則,只列印該行。
uj5u.com熱心網友回復:
您不需要預先計算行號。整個作業可以通過一個不太復雜的sed命令來完成。不過,您可能確實想撰寫腳本。例如:
#!/bin/bash
[[ $# -eq 3 ]] || {
echo "usage: $0 <context regex> <target regex> <replacement text>" 1>&2
exit 1
}
sed -si -e "/$1/ { s/\\<$2\\>/$3/; t1; p; d; :1; n; b1; }" ./*.java
假設要修改的檔案是當前作業目錄中的 java 源檔案,我相信您了解(松散的)引數檢查和使用訊息。
至于sed命令本身,
該
-s選項指示sed將每個引數視為一個單獨的流,而不是像將所有輸入連接到一個長流一樣操作。該
-i選項指示sed就地修改指定檔案。除非該行與第一個腳本引數給出的“背景關系”模式匹配,否則該
sed運算式對每一行都采用默認操作(逐字列印)。對于與背景關系模式匹配的行,
s/\\<$2\\>/$3/- 嘗試執行想要的替換- 和分別匹配單詞的開始
\<和\>結束邊界,這樣指定的模式將不匹配部分單詞(盡管如果目標模式允許,它可以匹配多個完整的單詞)
- 和分別匹配單詞的開始
t1- 如果進行了替換,則分支到 label1,否則p; d- 列印當前行并立即開始下一個回圈:1; n; b1- label1(只能通過分支訪問):列印當前行并讀取next 行,然后回圈回到 label1。這將列印檔案的其余部分,而無需進行任何測驗或替換。
示例用法:
/path/to/replace_first.sh 'String system' x y
值得注意的是,這確實向用戶展示了sed正則運算式和替換文本的解釋的一些細節,盡管這并沒有體現在示例用法中。
請注意,如果您確定要修改目標在每個檔案中的整體首次外觀,則可以通過洗掉背景關系模式位來簡化這一點。您還可以對背景關系、目標模式和/或替換文本進行硬編碼。如果您對所有三個都進行硬編碼,那么腳本將不再需要任何引數處理或檢查。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/432863.html
