Script de shell e seu uso
Isto pode ser feito com um simples shell script que faz uso de find ...|while read var ; do ... done
structure (muito comum em lidar com nomes de arquivos). O script bash abaixo opera no diretório atual (top-most) e leva um único argumento para o destino.
#!/bin/bash
find -name "genome.txt" -print0 | while IFS= read -r -d '' path
do
base=$(basename --suffix=".txt" "$path")
new_path="${1%/}"/"$base"$counter".txt"
echo "$path" "$new_path"
counter=$(( $counter +1 ))
done
> > > OBSERVAÇÃO < < < : o script usa echo
apenas para fins de teste. Quando estiver satisfeito com os caminhos resultantes, substitua echo
por mv
para mover todos os nomes de arquivos ou cp
para copiar todos os nomes de arquivos.
Exemplo:
bash-4.3$ tree
.
├── destination
├── dir1
│ └── genome.txt
├── dir2
│ └── genome.txt
├── dir3
│ └── genome.txt
└── move_enumerated.sh
4 directories, 4 files
bash-4.3$ ./move_enumerated.sh ./destination
./dir2/genome.txt ./destination/genome.txt
./dir3/genome.txt ./destination/genome1.txt
./dir1/genome.txt ./destination/genome2.txt
Melhorando o script para mais flexibilidade
Esse script pode ser melhorado para torná-lo mais genérico, onde o usuário pode especificar o nome do arquivo, o diretório superior a ser percorrido e o destino como argumentos da linha de comando:
#!/bin/bash
find "$2" -name "$1" -print0 | while IFS= read -r -d '' path
do
base=$(basename --suffix=".txt" "$path")
new_path="${3%/}"/"$base"$counter".txt"
echo "$path" "$new_path"
counter=$(( $counter +1 ))
done
Execução de teste:
bash-4.3$ ./move_enumerated.sh "genome.txt" "./testdir" "./testdir/destination"
./testdir/dir2/genome.txt ./testdir/destination/genome.txt
./testdir/dir3/genome.txt ./testdir/destination/genome1.txt
./testdir/dir1/genome.txt ./testdir/destination/genome2.txt
Sintaxe e teoria de operação
Em todo o script, é utilizado o command | while read variable ; do ... done
structure. Esta é uma abordagem muito comum, e é freqüentemente usada para evitar lidar com ls
e nomes de arquivos difíceis que podem quebrar scripts.
No lado esquerdo do pipe, temos o comando find
, que toma o diretório como argumento (e se isso não for fornecido, o GNU find
, que é usado no Linux, assume .
- o diretório de trabalho atual). As outras opções incluem -name
, que é o nome de arquivo específico que estamos pesquisando, e -print0
, que é usado para gerar resultados como delimitados por caractere
não imprimível. É freqüentemente usado para evitar a divisão na nova linha ou em outros caracteres, porque esses caracteres podem aparecer no próprio nome do arquivo e, como resultado, quebrar o script. while IFS= read -r -d '' ; do . . . done
No lado direito do tubo, temos while
structure. O loop read
com stdin
shell embutido é freqüentemente usado para% realIFS=
input, que neste caso vem do pipe. -r
-d ''
e
são necessários para garantir que recebamos nomes de arquivos com segurança e reconhecemos que cada item é delimitado com basename
--suffix=".txt"
.
O resto do script é bastante fácil. Extraímos o nome da base do arquivo usando o comando genome
. Como neste caso estamos lidando especificamente com a extensão conhecida e esperamos ter um único ponto no nome do arquivo, podemos usar "${3%/}"
para remover essa parte, deixando /
part. Em seguida, criamos um novo caminho para o arquivo, unindo o destino, o nome da base e a variável do contador. Observe que usamos a expansão de parâmetro com ./destination
argumento (pasta de destino) em nosso script aprimorado. Isso é feito para garantir que, independentemente de o usuário ter ou não adicionado ./destination/
caracteres na linha de comando ( /
ou counter
), extraímos apenas o nome do diretório simples e o associamos por meio de genome.txt
com basename. Observe também que a variável %code% não é configurada inicialmente, portanto, o primeiro nome de arquivo que recebermos será %code% Depois, a variável do contador será incrementada e, portanto, criada e mostrada quando lidamos com outros nomes de arquivos. p>
Para obter mais informações, leia Nomes de arquivo e nomes de caminho no Shell: como fazer corretamente .