상위 디렉토리 이름의 일부를 사용하여 일부 파일의 이름을 바꿉니다.

상위 디렉토리 이름의 일부를 사용하여 일부 파일의 이름을 바꿉니다.

특정 문자열 기준을 충족하는 하위 디렉터리의 파일을 식별한 다음 디렉터리 이름의 마지막 부분인 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를 사용합니다 .ksh93bash

관련 정보