サブディレクトリ名に基づいて特定のサブディレクトリのファイルを単一のディレクトリにコピーし、名前を変更します。

サブディレクトリ名に基づいて特定のサブディレクトリのファイルを単一のディレクトリにコピーし、名前を変更します。

以下は私のディレクトリツリーの一部です。

|-- 20070214_014700.a  
|   |-- info  
|   |-- processed  
|       |-- HH.EL..BHZ  
|       |-- AZ.AS..HHZ  
|       |-- (hundreds more)  
|   |-- raw  
|   |-- resp  
|-- 20100737_055560.a  
|   |-- info  
|   |-- processed  
|   |-- raw  
|   |-- resp  
|-- 20190537_028750.a  
|   |-- info  
|   |-- processed  
|   |-- raw  
|   |-- resp  

私は約13,000のディレクトリ(.aで終わる)を持っており、各ディレクトリには処理された各ディレクトリから単一のディレクトリにコピーしたいファイルを含む「処理された」サブディレクトリがあります。これらのファイルのいくつかは同じファイル名を持つことができるので、親ディレクトリに基づいて名前を変更したいと思います。私はあまり面倒ではありませんが、次のようになります。

20070214_014700_HH.EL..BHZ

完全なデータセットは3TBなので、Findを使用していくつかのディレクトリでテストしました。

find . -name processed -exec cp -r '{}' 'test/{}' \;

何らかの理由で、これはいくつかのファイルをtest /にダンプしますが、その中に別の処理済み/ディレクトリも作成します。コピーコマンドと名前変更機能の両方をfindに含める方法がわからないので、どんな提案でもいいでしょう。助けてくれてありがとう。

答え1

find . -type f -path "./*.a/processed/*" -exec sh -c '
for path; do
  prefix=${path%%.a/processed*}
  cp "$path" "test/${prefix##*/}_${path##*processed/}"
done
' sh {} +

オプションは-type f指定されたパスから通常のファイルを検索し、このオプションは結果を引数()として使用-execしてシェルスクリプトを起動します。ループ内では、各引数は変数に割り当てられます。find{} +forpath

例: 変数が次pathのような場合./20070214_014700.a/processed/AZ.AS..HHZ

  • prefix=${path%%.a/processed*}サフィックスの削除 - >./20070214_014700
  • ${prefix##*/}/最初 - >プレフィックスの削除20070214_014700
  • ${path##*processed/}また、プレフィックスを削除してファイル名を保持しました - >AZ.AS..HHZ

このコマンドで生成されたターゲットファイル名cptest/20070214_014700_AZ.AS..HHZ

関連情報