Renomeia certos arquivos com parte do nome do diretório pai

1

Eu gostaria de identificar arquivos que atendem a determinados critérios de string em subdiretórios, renomeie esses arquivos com a parte final do nome do diretório, 2 diretórios acima ("pd1"?), então eu gostaria de mover todos os nomes renomeados. arquivos para um diretório separado.

Mais detalhes: digamos que eu execute o código hipotético do diretório /x/y/z e nesse diretório existem diretórios com nomes como ' 20150416_110508_3006 '. Os arquivos que estou procurando renomear estão em (exemplo) ' /x/y/z/20150416_110508_3006/dicom ', exemplo de nome de arquivo ' o20150416_110508MPRAGESAGs002a1001.nii '. Os elementos importantes do nome do arquivo necessários para diferenciá-lo dos arquivos semelhantes são o prefixo " o ", o ' s002a ' no meio e a extensão " .nii ".

Eu queria renomear esses arquivos com a parte final do diretório pd1, neste caso ' 3006 ', então ' 3006.nii '. Então, depois de fazer isso para todos os arquivos aplicáveis, eu gostaria de mover os arquivos renomeados para um diretório em ' /x/y/z '.

    
por focusbob 12.08.2016 / 16:02

1 resposta

2

com zsh :

autoload zmv # best in ~/.zshrc
zmv -n '/x/y/z/*_*_(*)/dicom/o*s002a*.nii' '${f:h}/$1.nii'

Ou:

zmv -n '/x/y/z/*_*_(*)/dicom/o*s002a*.nii' '/x/y/z/somedir/$1.nii'

Para movê-los para somedir in /x/y/z .

Remova o -n para realmente fazer a renomeação depois que você estiver satisfeito de fazer o que quiser.

zmv detectaria renomeações conflitantes antes de iniciar qualquer renomeação. Fazer algo semelhante com outros shells como bash exigiria um script mais longo. Algo como:

#! /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

(não testado)

(remova o echo para realizar a renomeação).

Observe que as matrizes associativas bash (ao contrário do ksh93 ou zsh) têm um erro / limitação, pois você não pode ter elementos com uma chave vazia. Portanto, se você tiver alguns arquivos foo_bar_/dicom/*.nii , isso não funcionará corretamente, portanto, mesmo para essa abordagem programática, eu ainda usaria zsh ou ksh93 em vez de bash .

    
por 12.08.2016 / 16:10