Como extrair apenas o “basename” do diretório pai no shell?

4

Eu preciso renomear alguns arquivos usando scripts de shell, por uma certa "chave". Essa chave inclui as cadeias de caracteres e as partes extraídas do caminho do arquivo que obtenho com find .

Estou em um Mac, OSX El Capitan e estou usando o ZSH. Aqui está a árvore de diretórios :

├── 300x250
│   ├── 300x250-img-fallback.jpg
│   └── index/
├── 300x600
│   ├── 300x600-img-fallback.jpg
│   └── index/
├── 336x280
│   ├── 336x280-img-fallback.jpg
│   └── index/
└── 970x250
    ├── 970x250-img-fallback.jpg
    └── index/

Eu preciso renomear as pastas ../ index / para ../ c2_ [parentFolderName] / . É isso que estou tentando:

find . -type d -mindepth 2 -maxdepth 2 -exec sh -c 'echo -- mv "$0" "$(dirname "$0")"/"C2_"$(basename "$0/..")""' {} \;

Esta não parece ser a maneira correta de obter o basename do pai, infelizmente.

find . -name "*index" -exec sh -c 'echo -- mv "$0" "$(dirname "$0")"/"C2_"$(basename "$0/..")""' {} \;

Este é apenas uma variação que também não funciona (não há razão para que ele deva :)).

Eu sou muito novo no shell de scripts e estou tentando aprender o máximo possível de uma maneira agnóstica para shell , portanto, desconsidere que estou usando o ZSH atualmente.

    
por Alex Starbuck 30.08.2016 / 11:49

3 respostas

4

Melhor seria usar zsh de zmv :

autoload zmv # best in ~/.zshrc
zmv -n '(*)/index' '$1/C2_$1'

(remova -n quando feliz).

Para uma solução portátil ( POSIX sh ):

for dir in */index;  do
  mv -i -- "$dir" "${dir%/*}/C2_${dir%/*}"
done

(usando -i como um substituto do pobre para as verificações de sanidade zmv ).

Se você quisesse usar find portavelmente (POSIXly), você precisaria para esquecer -mindepth / -maxdepth , que você pode substituir com combinações de -path e -prune :

LC_ALL=C find . -path './*/*' -prune -name index -exec sh -c '
  for dir do
    top=${dir#./}
    top=${top%/*}
    mv -i -- "$dir" "$top/C2_$top"
  done' sh {} +

Uma diferença com as outras duas abordagens é que ele não seguirá links simbólicos e também procurará index em diretórios ocultos.

Eles fazem uso dos operadores padrão de expansão de parâmetro ${var#pattern} , ${var%pattern} descritos em inúmeros Q & como aqui ou no especificação do shell POSIX .

    
por 30.08.2016 / 12:40
2

Por que vale a pena, sua tentativa

find . -type d  -exec sh -c 'echo -- mv "$0" "$(dirname "$0")"/"C2_"$(basename "$0/..")""' {} \;

parece quase funcionar, exceto que basename não interpreta o ponto-ponto. Mas levar dirname deve dar o nome do pai e você pode pegar o basename disso. Algo parecido com isto:

$ mkdir -p 300x250/index 970x250/index
$ find . -name index -exec sh -c 'echo mv "$1" "$(dirname "$1")/C2_$(basename "$(dirname "$1")")"' sh {} \;
mv ./300x250/index ./300x250/C2_300x250
mv ./970x250/index ./970x250/C2_970x250

Como Stéphane mencionou, o primeiro argumento após sh -c "..." é considerado como o nome do script, que entra em $0 e é diferente dos parâmetros posicionais usuais de $1 para cima. Os últimos têm ferramentas específicas para trabalhar com eles, como shift e $@ , e não funcionam com $0 .

Para apenas um argumento, usar $0 poderia funcionar, mas como o nome do shell pode ser usado para outras finalidades, é preferível definir algo sensato (como sh ) ali e colocar os argumentos reais depois disso. / p>     

por 30.08.2016 / 14:47
0

Nunca trabalhei no ZSH , mas o código abaixo funciona muito bem no bash

SHW@SHW:/tmp/test1 # tree
.
├── 300x250
│   ├── 300x250-img-fallback.jpg
│   └── index
├── 300x600
│   ├── 300x600-img-fallback.jpg
│   └── index
├── 336x280
│   ├── 336x280-img-fallback.jpg
│   └── index
└── 970x250
    ├── 970x250-img-fallback.jpg
    └── index

8 directories, 4 files

SHW@SHW:/tmp/test1 # for i in 'find . -type d -name index'; do  mv $i 'dirname $i | cut -c3-'/c2_'dirname $i | cut -c3-'; done

SHW@SHW:/tmp/test1 # tree
.
├── 300x250
│   ├── 300x250-img-fallback.jpg
│   └── c2_300x250
├── 300x600
│   ├── 300x600-img-fallback.jpg
│   └── c2_300x600
├── 336x280
│   ├── 336x280-img-fallback.jpg
│   └── c2_336x280
└── 970x250
    ├── 970x250-img-fallback.jpg
    └── c2_970x250

8 directories, 4 files
    
por 30.08.2016 / 12:33

Tags