ファイル名が配列にある場合にのみ、ファイルを新しいディレクトリにコピーします。

ファイル名が配列にある場合にのみ、ファイルを新しいディレクトリにコピーします。

私はそれほど情熱的ではありませんが、zsh誰かに簡単なレイアップになると思います。

sourcedirtargetdir次のコマンドを使用してファイルを一括コピーできます。

$ 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これはデフォルトで-read / 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/ttypax/dev/ttypaxEOF応答の読み取り中に発生したか、/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

おすすめ記事