web-dev-qa-db-ja.com

トリプルドットワイルドカード

ソースコードの非常に大きなディレクトリ構造があり、操作が非常に困難です。ツールを実行して、Mavenのような構造に変換して、よりうまく機能するようにしたいと思います。作業が終了したら、ツールを再度実行して、Maven構造を元のひどい構造に戻します。私はさまざまなシェルに精通しており、数百のcpコマンドを含むスクリプトを作成できました。しかし、これを維持するのは難しいでしょう。

PERFORCEのトリプルドットワイルドカードのようなものを使用してファイルを移動またはコピーできるようにしたい:

現在の作業ディレクトリとすべてのサブディレクトリの下にあるすべてのファイルに一致します。 (スラッシュを含むすべてに一致し、サブディレクトリ間で一致します)

スクリプトには、次のようなコマンドが含まれます。

cp src/.../foobar/.../*.Java trusted/src/main/Java/.../foobar/.../*.Java

アイデアは、そのサブツリーの構造を維持しながら、ディレクトリのサブツリーを移動することです。

何か案は?

Gillesのrsyncソリューションに問題があります。これがテストスクリプトです。

#!/bin/bash

rm -rf source

mkdir -p source/server/src/com/bodhi/foobar/this
mkdir -p source/server/src/com/bodhi/foobar/that
mkdir -p source/server/src/com/bodhi/other

echo "Hello World" > source/server/src/com/bodhi/foobar/this/A.Java
echo "Hello World" > source/server/src/com/bodhi/foobar/that/B.Java
echo "Hello World" > source/server/src/com/bodhi/other/C.Java

rm -rf target
mkdir -p target/foobar/src/main/Java

rsync \
  --include='**/foobar/**/*.Java' \
  --include='**/foobar/**/' \
  --exclude='*' \
  --Prune-empty-dirs \
  source/server/src/ target/foobar/src/main/Java/
5
user1879313

このワイルドカードは、ksh93、bash≥4.3(ツリーにディレクトリへのシンボリックリンクがない場合は≥4.0)、およびzshに存在します。スペルは**です。 ksh93では、最初にset -o globstarでアクティブ化する必要があります。 bashでは、最初にshopt -o globstarでアクティブ化する必要があります。

ls -l src/**/foobar/**/*.Java

ただし、これでコピーが作成されるわけではありません。 cpのターゲットは単一のディレクトリであり、cpはワイルドカードによるマッチングを行いません。単一のcpコマンドを使用してファイルを別の場所にドロップすることはできません。

代わりに rsync を使用できます。ソースツリーのルートと宛先ツリーのルートを渡し、包含ルールと除外ルールを定義して、必要なファイルとそれらにつながるディレクトリのみをコピーします。 Rsyncは、パターンに一致する場合は空のディレクトリもコピーします。後で--Prune-empty-dirsを使用して削除することができます。

rsync --include='**/foobar/**/*.Java' --include='**/' \
      --exclude='*' --Prune-empty-dirs \
      src/ trusted/src/main/Java/

使用できるもう1つのツールは pax です。 paxは(rsyncとは異なり)POSIXによって定義されるという点で標準ですが、一部のLinuxディストリビューションではデフォルトのインストールから省略されています(ただし、パッケージとして常に利用可能です)。アプローチはrsyncに似ています:.Javaファイルを含め、残りを除外します。構文は少し奇妙です。ファイルを含めて名前を変更しないオリジナルのパターン置換、またはファイルを除外する空の置換を指定できます。先行ディレクトリは、必要に応じて宛先に自動的に作成されます。

pax -rw -s '/\.Java$/&/' -s '/.*//' src/* trusted/src/main/Java/