bash extrai o primeiro número do nome do arquivo

2

Estou tentando mover arquivos assim:

...
DLG023-00-01-sprite.TextGrid.json
DLG023-00-01.prosody.json
DLG023-01-01-sprite.ogg
DLG023-00-02-sprite.TextGrid.json
DLG023-00-02.prosody.json
DLG023-01-02-sprite.ogg
...
DLG028-00-01-sprite.TextGrid.json
DLG028-00-01.prosody.json
DLG028-01-01-sprite.ogg
...

em suas respectivas pastas, por exemplo: mova o arquivo para dialogue023/ quando ele começar com DLG023 ; para dialogue024/ quando começa com DLG024 ; e assim por diante.

Todos os arquivos e diretórios estão no mesmo nível.

Em outras palavras, estou tentando produzir comandos como este:

mv DLG023-00-01-sprite.ogg dialogue023/

Como posso extrair o primeiro número do nome do arquivo?

Até agora eu tenho isso:

for i in DLG*-*-*-sprite.ogg; do echo "${i//[^0-9]}";done

Mas isso gera todos os dígitos (por exemplo, 230001) quando eu quero apenas o primeiro (por exemplo, 23).

    
por Fabien Snauwaert 29.05.2015 / 13:59

4 respostas

1

Suponho que você esteja usando o OS X, que não possui a opção -t em mv . Isso será dolorosamente lento se o script estiver processando milhares de arquivos.

    for file in DLG*; do
    # Extract the three digits after DLG
    getnum=${file%%-*}
    getnum=${getnum#???}

    # make the directory dialogue### or exit if there is an error
    echo mkdir -p "dialogue${getnum}" || exit

    echo mv "$file" "dialogue${getnum}"
    done

Remova o echo antes de mkdir e mv se a saída for satisfatória.

    
por 29.05.2015 / 16:20
0

Você pode gerar o comando mv usando isto:

for f in DLG*; do echo "$f" | sed 's/DLG\([0-9]\+\).*/mv "
mv "DLG023-00-01.prosody.json" "dialogue023/"
[...]
mv "DLG028-00-01.prosody.json" "dialogue028/"
[...]
" "dialogue\/"/g'; done

Agora, o comando é impresso assim:

for f in DLG*; do echo "$f" | sed 's/DLG\([0-9]\+\).*/mv "
for f in DLG*; do echo "$f" | sed 's/DLG\([0-9]\+\).*/mv "
mv "DLG023-00-01.prosody.json" "dialogue023/"
[...]
mv "DLG028-00-01.prosody.json" "dialogue028/"
[...]
" "dialogue\/"/g'; done
" "dialogue\/"/g'; done | bash

Se é o que você quer, apenas canalize essa saída para bash e ela será executada:

for f in DLG*; do echo "$f" | sed 's/DLG\([0-9]\+\).*/mv "%pre%" "dialogue\/"/g'; done | bash
    
por 29.05.2015 / 15:50
0

Solução de uma linha usando find :

find . -name DLG* -exec bash -c 'DEST=$(echo "$0" | sed -r "s/DLG([0-9]+)-.*/dialogue/"); mkdir "$DEST"; mv "$0" "$DEST"' {} \;
  • O comando find procura por DLG* arquivos deste diretório.
  • Para cada resultado, execute a sentença bash -c .

Na sentença bash :

  • DEST=$(echo "$0" | sed -r "s/DLG([0-9]+)-.*/dialogue/"); seleciona cada resultado da pesquisa ( $0 ) e usando sed substitui todos os números antes da primeira - (DLG ([0-9] +) -. *) com dialogue seguindo esses números ( dialogue ) e colocar em uma variável chamada DEST .
  • mkdir "$DEST" cria a pasta necessária.
  • mv "$0" "$DEST"' move o arquivo para esse diretório.
por 29.05.2015 / 18:51
0

Algumas ideias:

for i in DLG*-\*-\*-sprite.ogg; do echo "${i//[^0-9]}" | head -c 2; echo ;done

Se você tiver certeza de que eles têm o mesmo tamanho:

for i in DLG*-\*-\*-sprite.ogg; do echo "${i:3:3}" ;done
    
por 29.05.2015 / 14:18