Bash如何替換
如何替換 $0
但保存舊值?
我正在嘗試將所有以“m”開頭的文件重命名為相同的名稱,除了第一個字元(或本例中的“m”)被刪除。
我的策略是:
- 列出所有文件,用
ls
- 過濾我想要的,用
egrep
- 在我想要的字元串旁邊生成我不想要的字元串,用空格分隔,
awk
例如,mfoo foo
- 餵
xargs
到mv mfoo foo
一些問題:
- 這是一個好策略嗎?
- 什麼是更好的?
我被困在第 3 步,下面是我解決問題的方法。
我在以下目錄中工作:
$ find . . ./cat ./mbar ./mbaz ./mfoo
我能夠快速獲得1-2:
$ ls | egrep '^m' mbar mbaz mfoo
第 3 步比較困難。我曾經
gsub
生成我想要的第二個字元串,但我不確定如何“將它與由空格分隔的原始值粘在一起”:$ ls | egrep '^m' | awk '{ gsub(/^./, ""); print }' bar baz foo
第 4 步對我來說很有意義,雖然我不確定如何完成第 3 步,所以我還不能完成它。下面是我認為它應該如何工作的一個例子:
$ echo mfoo foo | xargs mv $ find . . ./cat ./foo ./mbar ./mbaz
我想我已經接近了,我只需要找出如何保存舊值並將其列印在 gsubed 值旁邊。我已經嘗試了以下小範例,但它不起作用:
$ echo mfoo | awk ' pipe quote> { old = $0 } pipe quote> { new = gsub(/^./, "") } pipe quote> { print $old " " $new }' awk: illegal field $(mfoo), name "old" input record number 1, file source line number 4
- 如何替換
$0
但保存舊值?- 為什麼我會收到此錯誤?
ls | egrep '^m' | awk '{ x=$0; gsub(/^./, ""); $0 = x " " $0 }1' | xargs -l -t mv
Poixly的實現是通過以下
-L
選項xargs
:ls | egrep '^m' | awk '{ x=$0; gsub(/^./, ""); $0 = x " " $0 }1' | xargs -L 1 -t mv ls | egrep '^m' | awk '{ x=$0; gsub(/^./, ""); print x, $0 }' | xargs -L 1 -t mv
根據我對您之前關於
xargs
.我稍微修改了您的
awk
程式碼:它保留了原始行 ($0
),因為gsub
func 會破壞它。然後我們將舊的和新的放在一起以獲得我們想要發送到的行xargs
,然後mv
使用正確的參數呼叫以實現重命名。
這應該處理整個操作:
for file in m*; do mv "${file}" "${file#m}"; done
在你執行它之前,先檢查一下
for file in m*; do echo mv "${file}" "${file#m}"; done
這將
m*
glob 用於步驟 1 和 2,然後${file#m}
(從 的開頭刪除“m”${file}
)用於步驟 3,最後使用循環用於步驟 4。要回答您的 AWK 問題,您可以這樣做:
echo mfoo | awk '{ print $0, substr($0, 2) }'
AWK 變數不使用
$
,僅用於欄位;這就是您的錯誤的來源:AWK 理解$old
為“根據 的值編號的欄位的值old
”。如果將命令放在一個塊中(假設它們具有相同的模式),也更容易閱讀。修復你的腳本給echo mfoo | awk '{ old = $0; gsub(/^./, ""); print old, $0 }'