Linux

如何根據名稱與文件夾的對應關係移動文件?

  • November 12, 2022

我有這個父目錄 X 和這兩個子目錄 A 和 B(見圖 1):在此處輸入圖像描述文件夾 A 包含特定主題的文件,我想將這些文件移動到文件夾 B 中的其他相應文件夾。例如,在文件夾 A 中,我有很多以不同副檔名結尾的不同主題的文件(eeg.eeg、eeg.json、eeg.vhdr 和 eeg.vmrk)(見圖 2)。在此處輸入圖像描述

我想為每個主題獲取所有這些文件並將它們移動到 B 的子文件夾中,其中所有主題都有一個子文件夾:B>>“subject_id”>>ses-t1>>eeg。目標文件夾應該是每個參與者文件夾中的“eeg”文件夾。在此處輸入圖像描述.

所需的結果應如下圖所示(照片 3): 在此處輸入圖像描述

我認為,好消息是文件夾 A 中文件的起始名稱與主題子文件夾名稱相對應。例如,該文件以sub-CDPC0001 _ses-01_task-rest_eeg.eeg 開頭,類似於文件夾 B 中此特定主題的主題文件夾 ( sub_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 文件夾。我非常感謝您的回答,因為有很多數據,手動移動它們容易出錯且非常乏味。

首先,安裝 perlrename實用程序。您似乎使用的是 Mac,因此您可能需要使用brew,它已打包 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謂詞。如果沒有,請使用brew安裝 GNUfind並使用它而不是預設的 Mac find。如果沒有-regex你可以通過 OR-ing 幾個 -name 謂詞一起來做到這一點(在括號中強制優先級):

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

另請注意,重命名的-n選項使其成為空執行,因此它只會顯示它會做什麼而不實際重命名任何文件。當您確認它可以執行您想要的操作時,刪除-n,或將其替換為詳細輸出。-v如果它不完全正確,請修改重命名腳本,直到它按您想要的方式工作。

順便說一句,這假設 B/ subject / 和 B/ subject /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

引用自:https://unix.stackexchange.com/questions/724482