「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
必要な 2 番目の文字列を生成しましたが、「スペースで区切られた元の値と結合する」方法がわかりません。
$ 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
」として理解します。コマンドを 1 つのブロックに配置すると読みやすくなります (同じパターンであると仮定)。スクリプトを修正すると、
echo mfoo | awk '{ old = $0; gsub(/^./, ""); print old, $0 }'
答え2
ls | egrep '^m' | awk '{ x=$0; gsub(/^./, ""); $0 = x " " $0 }1' | xargs -l -t mv
ポジックス-リー実装は次-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
。次に、古い行と新しい行を組み合わせて、送信先の行を取得し、適切な引数でxargs
呼び出してmv
名前の変更を実行します。
答え3
より良い戦略は、rename
コマンドを使用することです。
このコマンドの正確な構文はディストリビューションに固有のものであることに注意してくださいman
。特定のバージョンのディストリビューションのページを参照してください。たとえば、Perl 実装を持つ Ubuntu ではrename
、正規表現を使用できます。
rename -nono 's/^m//' m*
注意:-nono
実際に名前の変更を実行するにはフラグを削除します。