私はそれほど情熱的ではありませんが、zsh
誰かに簡単なレイアップになると思います。
sourcedir
targetdir
次のコマンドを使用してファイルを一括コピーできます。
$ find sourcedir -type f -exec cp {} targetdir \;
cp
ファイル名が次のいずれかと一致する場合にのみ、この操作を実行できます。
top directory
fileA <= directories have same name as single file they enclose
fileA.pdf <= file to move
another file
another file.pdf <= do NOT move
still133another4544file
still133another4544file.pdf <= file to move
文字通り何千ものものを渡す必要がありますが、選択した数個だけを移動するには、名前があり、ファイルに入れるか、スクリプトに直接入れることができます。
単純なシェルスクリプトを維持できます。 Rubyも許可します。
ベストアンサー1
まず、私が作成したサンプルツリーは次のようになります。
{ pwd
for d in ./*/
do cd "$d"
printf '\t%s\n' "${d#??}"
printf '\t\t%s\n' *
cd ..
done
}
/tmp/top
another file/
another file.pdf
fileA/
fileA.pdf
otherdir/
1
2
3
stillanother4544file/
stillanother4544file.pdf
今何もする必要はありません。サンプルツリーをミラーリングするためにツリーを作成し、いくつかの異常値を追加しました。
しかし、私はこれをするように提案します:
pax -rwis'|^./\([^/]*\)/\(\1\....\)$|\2|' -s'|.*||' . ../tgt
pax
これはデフォルトで-r
ead / riteモード(直接コピーモード)-w
でPOSIX標準ユーティリティを呼び出すことです。コピーモードでは、意識モードのpax
ようにアーカイブは生成されませんが、その引数で見つかったすべてのファイル(ここでは現在のディレクトリにルートを持つツリーのみ)および/または標準入力((この場合は空))に名前を付けます。という名前のディレクトリです(ここにあります)。tar
-w
[...pattern...]
.
../tgt
今私はあなたがツリー全体を移動したくないことを知っています。これらのほとんどは-s
代替引数で処理されます。sed
ここで行ったように、正規表現スタイルステートメントに基づいて出力ファイルの名前を変更できます。私は2つの-s
交換ドアを使用します。最初は、すべての入力一致の名前を次のように変更します。
./dirname/samename.???
...到着...
samename.???
...出力時にコピーされたすべてのファイルに直接収まるように出力ツリーを平坦化します../tgt
。./dirname/
各ディレクトリの親ディレクトリを維持するには、\2
最初の-s
置き換えられた部分を&
。
ファイル名がpax
-s
正常に一致し、置換によって変更された場合、残りの-s
代替パラメータは再試行されず、まだ一致していないファイルにのみ残りの名前変更正規表現が試行されます。これは、現在のディレクトリ内のすべてのファイルが次の種類のパス名を持つことを意味します。
./dirname/samename.???
...最後のパス名コンポーネントと最初の-s
代替文とすべての項目を除くすべての項目を正常に選択して削除しました。その他現在のディレクトリのファイルは、2番目の代替ファイルで完全に置き換えられます-s|.*||
-s
。これはpax
、空の文字列を置き換えるファイル名が処理リストから削除されるためです。
pax
すべてのジョブが処理されたら、選択したファイルを実際にコピーする前に最後のジョブを完了する必要があります。これは-i
私が指定したインタラクティブな名前変更オプションであり、これがあなたに適していると思います。
からman pax
:
-i
- 対話的にファイル名またはアーカイブメンバーの名前を変更します。一致する各プロファイルメンバーについて
pattern
オペランドまたはファイルオペランドと一致する各ファイルは、ファイル名、ファイルモード、および変更時刻の入力をpax
求められます。次に、1行を読みます。この行が空の場合は、ファイルまたはアーカイブメンバーをスキップします。行が単一のピリオドで構成されている場合、ファイルまたはアーカイブメンバーは名前を変更せずに処理されます。それ以外の場合、その名前はその行の内容に置き換えられます。次の場合、ゼロ以外の終了状態で直ちに終了します。/dev/tty
pax
/dev/tty
pax
EOF
応答の読み取り中に発生したか、/dev/tty
読み取りまたは書き込みのために開くことができません。
ATTENTION: pax interactive file rename operation.
-rw-r--r-- Oct 17 04:30 stillanother4544file.pdf
Input new name, or a "." to keep the old name, or a "return" to skip this file.
Input > .
Processing continues, name unchanged.
ATTENTION: pax interactive file rename operation.
-rw-r--r-- Oct 17 04:30 another file.pdf
Input new name, or a "." to keep the old name, or a "return" to skip this file.
Input >
Skipping file.
ATTENTION: pax interactive file rename operation.
-rw-r--r-- Oct 17 04:30 fileA.pdf
Input new name, or a "." to keep the old name, or a "return" to skip this file.
Input > .
Processing continues, name unchanged.
-i
したがって、現在のディレクトリにある6つのファイルのうち3つだけがインタラクティブな名前変更プロンプトに入ることができます。これら3つのうち2つのみが次のようになります../tgt
。
ls -l ../tgt
-rw-r--r-- 1 mikeserv mikeserv 0 Oct 17 04:30 fileA.pdf
-rw-r--r-- 1 mikeserv mikeserv 0 Oct 17 04:30 stillanother4544file.pdf