특정 문자열 기준을 충족하는 하위 디렉터리의 파일을 식별한 다음 디렉터리 이름의 마지막 부분인 2개 디렉터리("pd1"?)를 사용하여 해당 파일의 이름을 바꾼 다음 이름이 바뀐 모든 파일을 별도의 디렉터리로 이동하고 싶습니다.
자세한 내용: 디렉터리에서 가상 코드를 실행하고 /x/y/z
해당 디렉터리 내의 디렉터리에 " 20150416_110508_3006
"와 유사한 디렉터리 이름이 있다고 가정해 보겠습니다. 이름을 바꾸려는 파일은 (예) " /x/y/z/20150416_110508_3006/dicom
", 예 파일 이름 " o20150416_110508MPRAGESAGs002a1001.nii
"에 있습니다. 유사한 파일과 구별되는 파일 이름의 중요한 요소는 접두사 " o
", s002a
중간 " " 및 확장자 " .nii
"입니다.
3006
이 파일의 이름을 pd1 디렉토리의 마지막 부분(이 경우 " ", 즉 " ") 으로 바꾸고 싶습니다 3006.nii
. 그런 다음 적용 가능한 모든 파일에 대해 이 작업을 수행한 후 이름이 바뀐 파일을 /x/y/z
" "의 디렉터리 로 이동하고 싶습니다 .
답변1
그리고 zsh
:
autoload zmv # best in ~/.zshrc
zmv -n '/x/y/z/*_*_(*)/dicom/o*s002a*.nii' '${f:h}/$1.nii'
또는:
zmv -n '/x/y/z/*_*_(*)/dicom/o*s002a*.nii' '/x/y/z/somedir/$1.nii'
somedir
매체 로 이동하십시오 /x/y/z
.
-n
원하는 대로 작동하고 있다는 사실이 만족스러우면 삭제하여 실제로 이름을 바꾸세요.
zmv
이름 바꾸기가 시작되기 전에 충돌하는 이름 바꾸기가 감지됩니다. 다른 셸에서 유사한 작업을 수행하려면 bash
더 긴 스크립트가 필요합니다. 그것은 다음과 같습니다:
#! /bin/bash -
typeset -A seen
shopt -s nullglob
for file in /x/y/z/*_*_*/dicom/o*s002a*.nii; do
tag=${file%/*/*}
tag=${tag##*_}
if [[ ${seen[$tag]} ]]; then
printf >&2 '"%s" and "%s" both map to "%s"\n' "$file" "${seen[$tag]}" "$tag"
exit 1
fi
seen[$tag]=$file
done
for tag in "${!seen[@]}"; do
echo mv -i -- "${seen[$tag]}" "/x/y/z/somedir/$tag"
done
(테스트되지 않음)
( echo
이름을 바꾸려면 삭제하세요).
bash
연관 배열(ksh93 또는 zsh와 반대)에는 요소가 널 키를 가질 수 없다는 버그/제한 사항이 있습니다 . 따라서 일부 파일이 있으면 foo_bar_/dicom/*.nii
작동하지 않으므로 이 프로그래밍 접근 방식에서도 여전히 or zsh
를 사용합니다 .ksh93
bash