Como usar os parâmetros da linha de comando para selecionar e alterar um grupo de nomes de arquivos

0

Eu tenho usado um shell script simples colocado na minha pasta user / .bin; Seu trabalho é muito simples, copie os arquivos especificados $ 1 e renomeie para $ 2; pelo menos eu pensei que fosse assim tão simples ...

A situação de uso é esta, eu tenho uma nomenclatura de arquivo para minhas notas de programação. O sistema é simples, um número crescente seguido por uma letra, o resto do nome do arquivo contém apenas letras e sublinhados. Notas para um determinado tópico são chamadas: 16115P-foobar.md enquanto os arquivos de código para esse tópico são: 16115P-foobar.c 16115P-barfoo.h etc.

À medida que o programa avança com cada lição, copio todos os arquivos do programa antes de modificá-los; De modo a ter arquivos de cada etapa do curso. Como é requerido de mim modificar o programa usando o tópico de lições; A primeira coisa que faço é copiar e renomear os arquivos. O script deve duplicar cada arquivo e renomeá-los, alterando apenas o número sequencial, que é da minha nomenclatura padrão:

por exemplo. 16115P-foobar.c deve ser alterado para 17121P-foobar.c ... etc.

O novo número é especificado pelo usuário (somente eu) por meio do segundo parâmetro de linha de comando; não é automatizado pelo script.

#!/bin/bash

for filename in $1*
do
    #
    # Copy and rename files
    #
    newname='echo "$filename" | tr "$1" "$2"'
    echo $filename $newname
    cp $filename $newname
done

Quando eu analiso os nomes dos meus arquivos assim:

:~/blah/blah/code$ copy_and_rename 16115P 17121P
16115P-file.c 27221P-file.c
16115P-input.c 27221P-input.c
16115P-main.c 27221P-main.c
16115P-output.c 27221P-output.c
16115P-recordshop.h 27221P-recordshop.h
16115P-utils.c 27221P-utils.c

Eu vejo agora que tr não é o comando correto para usar aqui; Eu apreciaria alguma ajuda.

Atenciosamente.

    
por iain 06.01.2016 / 15:44

1 resposta

1

Esta é uma tarefa mais adequada para expressões regulares. Aqui eu uso expressões regulares com awk (já que não estou familiarizado com o comando rename e perl regex, sim - é uma vergonha para mim). A idéia básica é que pegamos o nome do arquivo, nos livramos de todos os números (assumindo que você é muito bom em manter sua própria nomenclatura e não haverá números após P- part).
Os nomes de arquivos são fornecidos como argumentos de linha de comando, podem ser digitados um por um ou usados com curinga como mostrado aqui. Em seguida, lemos o novo número do usuário de forma interativa e inserimos esse novo número para cada nome de arquivo cortado.

$ ls
16115P-barfoo.h  16115P-foobar.c  16115P-foobar.md  updateNames.sh*
$ ./updateNames.sh 16115*                                                                                                        
Enter new number for all specified files: 
17121
17121P-barfoo.h
17121P-foobar.c
17121P-foobar.md
$ cat updateNames.sh                                                                                                             
#!/bin/bash

if [ $# -eq 0  ]; 
then
    echo "<<< Error: no arguments provided"
    exit 1
fi

echo "Enter new number for all specified files: " 
read NEWNUMBER
for file in "$@";
do
  BASE="$(echo "$file" | awk -F '-' '{ gsub( /[[:digit:]]/,""); print }')"
  echo $NEWNUMBER""$BASE
  # uncomment this line for actual copying
  # cp "$file" $NEWNUMBER""$BASE
done

$ 
    
por Sergiy Kolodyazhnyy 07.01.2016 / 13:57