Bash

如何替換 $0 但保存舊值?

  • April 10, 2017

我正在嘗試將所有以“m”開頭的文件重命名為相同的名稱,除了第一個字元(或本例中的“m”)被刪除。

我的策略是:

  1. 列出所有文件,用ls
  2. 過濾我想要的,用egrep
  3. 在我想要的字元串旁邊生成我不想要的字元串,用空格分隔,awk例如,mfoo foo
  4. xargsmv 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),因為gsubfunc 會破壞它。然後我們將舊的和新的放在一起以獲得我們想要發送到的行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 }'

引用自:https://unix.stackexchange.com/questions/357993