폴더 이름에 따라 파일을 이동하는 방법은 무엇입니까?

폴더 이름에 따라 파일을 이동하는 방법은 무엇입니까?

이 상위 디렉터리 X와 두 개의 하위 디렉터리 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

먼저 Perl rename유틸리티를 설치합니다. 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

관련 정보