"$0"を置き換えながら古い値を保存する方法は?

最初の文字(またはこの場合は「m」)が削除されることを除いて、「m」で始まるすべてのファイルの名前を同じ名前に変更しようとします。

私の戦略は次のとおりです。

  1. 次の場所にあるすべてのファイルを一覧表示します。ls
  2. 欲しいものをフィルタリングし、egrep
  3. 必要な文字列の横に不要な文字列をスペースで区切って生成します。awk例:mfoo foo
  4. xargs次へmv mfoo foo

いくつかの問題:

  • これは良い戦略ですか?
  • 何が良いですか?

ステップ3で詰まっています。問題を解決した方法は次のとおりです。

私は次のディレクトリで作業しています。

$ find .
.
./cat
./mbar
./mbaz
./mfoo

1~2個を早く得ることができます。

$ ls | egrep '^m'
mbar
mbaz
mfoo

ステップ3はもっと難しいです。私は私が望んでいた2番目の文字列を生成しましたが、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以前の値を変更しますが、保存する方法は?
  • このエラーが発生するのはなぜですか?

ベストアンサー1

これはジョブ全体を処理する必要があります。

for file in m*; do mv "${file}" "${file#m}"; done

走る前に必ず確認してください

for file in m*; do echo mv "${file}" "${file#m}"; done

これはm*ステップ1と2にglobを使用し、ステップ3には${file#m}(最初から「m」を削除${file})、最後にステップ4にはループを使用します。

AWKの質問に答えるには:

echo mfoo | awk '{ print $0, substr($0, 2) }'

$AWK変数は、エラーが発生したフィールドには使用されません。 AWKはこれを$old「値に応じて番号付けされたフィールド値old」として理解します。また、コマンドをブロックに入れると読みやすくなります(同じパターンを持っていると仮定)。スクリプト提供の変更

echo mfoo | awk '{ old = $0; gsub(/^./, ""); print old, $0 }'

おすすめ記事