使用父目录名称的一部分重命名某些文件

使用父目录名称的一部分重命名某些文件

我想识别子目录中满足某些字符串条件的文件,然后使用目录名的最后部分重命名这些文件,向上 2 个目录(“pd1”?),然后我想将所有重命名的文件移动到单独的目录。

更详细:假设我从目录运行假设的代码/x/y/z,并且该目录中的目录名称类似于“ 20150416_110508_3006”。我要重命名的文件位于(示例)“ /x/y/z/20150416_110508_3006/dicom”中,示例文件名“ o20150416_110508MPRAGESAGs002a1001.nii”。与类似文件区分开来的文件名的重要元素是前缀“ o”、s002a中间的“”和扩展名“ .nii”。

我想用 pd1 目录的最后部分重命名这些文件,在本例中为“ 3006”,因此为“ 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将在开始任何重命名之前检测冲突的重命名。对其他 shell 执行类似的操作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文件,则无法正常工作,因此即使对于这种编程方法,我仍然会使用zshorksh93代替bash.

相关内容