フォルダ名に基づいてファイルを移動する方法は?

フォルダ名に基づいてファイルを移動する方法は?

この親ディレクトリXと2つの子ディレクトリAとBがあります(写真1を参照)。ここに画像の説明を入力してください。フォルダAには特定のトピックのファイルが含まれており、これらのファイルをフォルダBの対応するフォルダに移動したいと思います。たとえば、フォルダAには、さまざまな拡張子(eeg.eeg、eeg.json、eeg.vhdr、およびeeg.vmrk)で終わるさまざまなテーマの多くのファイルがあります(写真2を参照)。ここに画像の説明を入力してください。

各トピックのすべてのファイルをインポートし、すべてのトピックのサブフォルダーB>>"subject_id">>ses-t1>>eegのあるBのサブフォルダーに移動したいと思います。宛先フォルダは、各参加者フォルダ内の「eeg」フォルダである必要があります。ここに画像の説明を入力してください。

必要な結果は以下の画像と同じでなければなりません(図3)。 ここに画像の説明を入力してください。

私の考えでは、フォルダAのファイルの開始名がテーマサブフォルダ名と一致するという利点があります。たとえば、ファイルは次から始まります。サブCDPC0001_ses-01_task-rest_eeg.eeg、フォルダBのこの特定のテーマのテーマフォルダに似ています(子_CDPC0001)

過去にはこの目的のための小さなスクリプトがありましたが、今はこの配列ではうまくいきません。

for dir in $(ls -d */ses-t1); do
find "./$dir/" -name '*_eeg.eeg' -exec mv {} "$dir/eeg" \;
find "./$dir/" -name '*_eeg.vhdr' -exec mv {} "$dir/eeg" \;
find "./$dir/" -name '*_eeg.vmrk' -exec mv {} "$dir/eeg" \;
find "./$dir/" -name '*_eeg.json' -exec mv {} "$dir/eeg" \;
#find "./$dir/" -name '*_anat.nii.gz' -exec mv {} "$dir/t1" \;
done

フォルダAのすべてのファイルが一覧表示されますが、希望のeegフォルダに移動することはできません。データが多く、手動で移動するのはエラーが発生しやすく、非常に退屈なので、あなたの答えに本当に感謝します。

答え1

まず、Perlrenameユーティリティをインストールします。 Macを使っているようですので、以下を試してみてください。醸造、すでにPerl renameパッケージが含まれています。 - 参照https://formulae.brew.sh/formula/rename

インストールが完了したら、次のコマンドを実行できます。

$ find A/ -regex '.*_eeg.\(eeg\|vhdr\|vmrk\|json\)' \
    -exec rename -n 's=^.*/(sub-[^_]*)_=B/$1/eeg/$1_=' {} +

find注:現在私のMacにどのバージョンがインストールされているのかわかりません。私はそれがFreeBSDバージョンfindであり、述語があると仮定します-regex。それ以外の場合は、brewGNUをインストールしfindてデフォルトのMacの代わりに使用してくださいfind。そうでない場合は、-regex複数の-name述部をORで連結することでこれを達成できます(優先順位を強制するために括弧内に入れます)。

find A/ \( -name '*_eeg.eeg' -o -name '*_eeg.vhdr' -o -name '*_eeg.vmrk' -o -name '*_eeg.json' \) -exec rename ...`

また、[名前の変更]-nオプションを使用するとテスト的に実行されるため、実際にファイル名を変更せずに実行するアクションのみが表示されます。要件を満たしていることが確認されたら、削除または置換して-n詳細な出力を取得します。-v名前変更スクリプトが正しくない場合は、目的の方法で機能するまで変更してください。

しかし、これはB /を想定しています。トピック/そしてB /トピック/eeg/ はすでに存在します。そうでない場合は、ファイル名を変更する前に名前変更スクリプトを使用してディレクトリを作成する場合は、変更s===操作の前に次を挿入してください。

if (m=^.*/(sub-[^_]*)_=) { mkdir "B/$1"; mkdir "B/$1/eeg" };

実行の例テキスト写真このtouchコマンドは、.vhdr、.vmrk、および.jsonファイル(私のA /ディレクトリにある場合)にも機能します。

$ mkdir -p A B/sub-CDPC0001/eeg/
$ touch A/sub-CDPC0001_ses-01_task-rest_eeg.eeg

$ find A/ -regex '.*_eeg.\(eeg\|vhdr\|vmrk\|json\)' \
    -exec rename -v 's=^.*/(sub-[^_]*)_=B/$1/eeg/$1_=' {} +
A/sub-CDPC0001_ses-01_task-rest_eeg.eeg renamed as B/sub-CDPC0001/eeg/sub-CDPC0001_ses-01_task-rest_eeg.eeg

関連情報