Bash は複数のディレクトリから複数の対応するバックアップ ディレクトリにファイルをコピーします。

Bash は複数のディレクトリから複数の対応するバックアップ ディレクトリにファイルをコピーします。

dir1,dir2,dir3,dir4Linux ボックスには複数のディレクトリ { } があります。

各ディレクトリには複数のファイル (拡張子が同じ、たとえば .zip) があり、それらを対応するディレクトリ { dir1-bck,dir2-bck,dir3-bck,dir4-bck} にバックアップする必要があります。フォルダ全体をバックアップする必要はなく、各フォルダ内のいくつかのファイルだけをバックアップします。

dir1/*.zip提供されたディレクトリのリストにドロップされたファイルをコピーするにはどうすればよいでしょうかdir1-bck。現在使用しているのは、次のディレクトリです。

cp -r src/dir1/*.zip dest/dir1-bck/
cp -r src/dir2/*.zip dest/dir2-bck/
cp -r src/dir3/*.zip dest/dir3-bck/
cp -r src/dir4/*.zip dest/dir4-bck/

これは機能しますが、改善の余地が非常に大きいです。

マニュアルページやフォーラムの同様の投稿を見ると、xargsこれがこの作業に適したツールだと感じますが、うまく使いこなせないようです。

答え1

おそらくforループがちょうど良いでしょう。正確な形式は、これらのディレクトリの名前の付け方によって異なります。次のようになります。

cd src || exit 1
for d in "dir"{1..4}; do
   cp -r "$d"/*.zip "../dest/$d-bck/"
done

ノート:

  • src( )内から作業するのが良いのでcd src、変数には追加の処理なしでターゲット パスで使用できる文字列が含まれます。ターゲット パスは、../この場合は先頭に追加することで調整されましたが、一般的には のようになる場合があります"/full/path/to/dest/$d-bck/"
  • dir名前をスペースなどで置き換える場合に備えて引用符を付けました。$d同じ理由で二重引用符を付けました。もっと
  • ファイルの場合*.zipは必要ありません-r

あるいは、次のfor行も考えられます。

for d in dir1 dir2 dir3 dir4; do

これは、任意の名前のディレクトリをいくつか指定する必要がある場合に便利です。または、次のようになります。

for d in *; do

次のように、いくつかの改善を行うことができます。

( cd src || exit 1
for d in *; do
   dst="../dest/$d-bck/"
   [ -d "$d" ] && mkdir -p "$dst" && cp -- "$d"/*.zip "$dst"
done )

改善点:

  • すべてのコードはサブシェル ( (…)) 内で実行されるため、cdターミナルにコードを貼り付けても現在のシェルには影響しません。スタンドアロン スクリプト (ソースではなく実行) にする必要がある場合、サブシェルは無関係になります。
  • $dディレクトリかどうかを確認します。
  • 宛先ディレクトリを作成しようとします (存在しない場合)。
  • cp宛先ディレクトリが存在する場合にのみ続行します。
  • を使用しております二重ダッシュin case は$dダッシュで始まります。

起こりうる問題:

  • "$d"/*.zip項目が多すぎる可能性があります ( Argument list too long)。元のコマンドにも同じように「欠陥」があります。「各ディレクトリにファイルが数個だけ」ある場合は、問題にはなりません。
  • "$d"/*.zip展開されない可能性があります (*リテラルのままになります)。害はありませんが、宛先ディレクトリは事前に作成されます。このような場合にディレクトリの作成を抑制するための追加ロジックが必要になる場合があります。
  • スニペット全体の終了ステータスは最後の のみに依存します[ … && mkdir … && cp …。以前の問題が終了ステータスに影響を与えるようにするには、追加のロジックが必要です。

関連情報