Perlの rename(1) と似ていますが、ファイルをコピーするスクリプトですか?

Perlの rename(1) と似ていますが、ファイルをコピーするスクリプトですか?

だからこんなことがあります。rename(1)真珠もの。それは私の仕事にぴったりです。ただ基本cp的にmv

この目標を達成する方法は?私はかなり多くの名前変更規則を持っており、すべてs|/foodir/|/|;s|/bardir/|/|圧縮された形式で表現され、コピーする必要がある数行のファイルパターンがあります。

次のように見えます。

rename -v 's|/pars/|/|; s|/fts/|/|; s|innobase/include|include|' \
    storage/{innobase,xtradb}/pars/{pars0grm.cc,pars0grm.y,pars0lex.l,lexyy.cc} \
    storage/{innobase,xtradb}/fts/{fts0blex.cc,fts0blex.l,fts0pars.cc,fts0pars.y,fts0tlex.cc,fts0tlex.l} \
    storage/innobase/include/fts0[bt]lex.h

答え1

これは仕事です。公園pax標準 POSIX コマンドです。一部のLinuxディストリビューションでは、デフォルトのインストールからこれを省略するため、パッケージを明示的にインストールする必要があります。基本的な sed 正規表現の置換だけで Perl のすべての機能を使用することはできませんが、ユースケースには十分です。

pax -rw -pe -s'|/pars/|/|' -s'|/fts/|/|' -s'|innobase/include|include|' …

もっと強力なものが欲しいならここに扱いにくいはいzmvこのウェブサイトには多くの例があります。、例えばファイル名のナビゲーション、コピー、変換コピーするときにファイル名を変更する方法は?

答え2

あなたのように、私は他のツールやフレーズを必要としませんcopyrename私はこの質問に答えました!cpで正規表現を使用する。あなたの便宜のためにここに掲載されます。

rename私はPerlスクリプト(Robin BarkerとLarry Wallを書く)の正規表現構文が大好きです。たとえば、次のようになります。

rename "s/OldFile/NewFile/" OldFile*

OldFile.cそれぞれとOldFile.hに名前が変更されました。NewFile.cNewFile.h

コピーコマンドを使用して同じ結果を得たいと思います。

copy "s/OldFile/NewFile/" OldFile*

だから私はスクリプトをコピーし、renameステートメントをcopy viaに変更しましたFile::Copy。お待ちください! Perl-regex構文を使用したコマンドのコピー: ジェシーワード/ウォフィー

答え3

sedさて、だから私はこんなに普通で古いものから抜け出すことができました。

ls -1 \
    storage/{innobase,xtradb}/pars/{pars0grm.cc,pars0grm.y,pars0lex.l,lexyy.cc} \
    storage/{innobase,xtradb}/fts/{fts0blex.cc,fts0blex.l,fts0pars.cc,fts0pars.y,fts0tlex.cc,fts0tlex.l} \
    storage/innobase/include/fts0[bt]lex.h \
    | sed -re 'h; s|/pars/|/|; s|/fts/|/|; s|innobase/include|include|; H; x; s|\n| |' \
    | xargs -L1 cp -v \
    ;

スクリプトsedはそれほど単純ではないので(後でのために)ステップバイステップで説明します。

  • h現在の行(「パターン空間」)をレジスタ(「保持空間」)にコピーします。
  • 毎回、いつものようにパターンスペースを編集し、sスペースを変更せずに保持します。
  • H 追加今行をHolding Registerに編集します - 最終的に保留します。二つ行、古いファイル名と新しいファイル名、そして\nもちろん含まれている文字。
  • x 言うパターン空間を持つ保持空間、保持レジスタから古いペアと新しいペアを効果的にロードします。
  • s|\n| |2行を1行にマージし、スペースで区切ります。
  • p最後に、結果は暗黙的に(sed呼び出しなしで)印刷されます-n

要約すると、パイプラインは次のように動作します。

  • ls -1すべてのglobを実際の既存のファイルのファイル名に拡張し、1行に1つずつ印刷します。
  • sed"$old_filename $new_filename"もう一度行に1つのファイルに変更してください。
  • xargs -L1cp -v $old_filename $new_filenameすべての回線に通話があります。

それだけです!

関連情報