O site Dicas-L trouxe na ultima semana 2 formas de renomear multiplos arquivos (aqui e aqui)
São ambas formas interessantes, porém ao meu ver consomem muito recursos da maquina, sem falar que são um tanto… feios… (nada contra - o que importa é que funcione)
Vou utiliza-los como exemplo de como podemos tornar algo melhor e mais prático (se o tempo permitir).
Vamos dividir as paradas:
Agora vamos tomar um cuidado: arquivos com espaço no nome
Bom, o for pode iterar sobre uma lista de argumentos. As mascaras de nome de arquivo são expandidos pelo shell durante a execução, logo…
Agora, a rotina de alteração do nome do arquivo de destino é complicadissima, depende de um ou mais sub-processos. Isso poderia ser…
Que, inserido no for…
Interessante, certo? Nenhum sub-processo, exceto o inumeros mv que serão executados. Existem outras formas de fazer a mesma coisa
(rodem as linhas acima sem o mv do xargs para entende-las – é metaprogramação)
Agora… tudo isso é muito bonito mas… veja se o seu computador possui os comandos mmv ou rename (que facilitam Absurdamente a tarefa)
Simples, não?
Tudo depende do tempo que temos e das nossas necessidades. Mesmo que o rename/mmv sejam uteis, pode ser que a forma com awk / sed valha mais a pena pois o ls pode ser substituido por um find (ja pensou nisso?)
#Forma 1
for o in $(ls -1 *.txt); do
mv $o $(echo $o | awk -F. '{print $1".htm"}');
done
#Forma 2
for i in `ls *.txt`; do
mv $i $(echo `basename $i .txt`.html)
done
São ambas formas interessantes, porém ao meu ver consomem muito recursos da maquina, sem falar que são um tanto… feios… (nada contra - o que importa é que funcione)
Vou utiliza-los como exemplo de como podemos tornar algo melhor e mais prático (se o tempo permitir).
Vamos dividir as paradas:
altera() { mv $1 $(echo `basename $1 .txt`.html) ; }
for i in `ls *.txt`; do
altera $i
done
Agora vamos tomar um cuidado: arquivos com espaço no nome
altera() { mv "$1" $(echo `basename "$1" .txt`.html) ; }
for i in `ls *.txt`; do
altera "${i}"
done
Bom, o for pode iterar sobre uma lista de argumentos. As mascaras de nome de arquivo são expandidos pelo shell durante a execução, logo…
for i in *.txt ; do
altera "${i}"
done
Agora, a rotina de alteração do nome do arquivo de destino é complicadissima, depende de um ou mais sub-processos. Isso poderia ser…
altera() { mv "$1" "${1%.txt}.html" ; }
Que, inserido no for…
for i in *.txt ; do
mv "${i}" "${i%.txt}.html"
done
Interessante, certo? Nenhum sub-processo, exceto o inumeros mv que serão executados. Existem outras formas de fazer a mesma coisa
ls *.txt | awk -F. -v OFS=. '{ O=$0; $NF="html" ;printf "\"%s\" \"%s\"\n",O,$0 }' | xargs -n 2 mv
ls *.txt | sed 's#^\(.\+\)\.[^.]\+$#"&" "\1.html"#g' | xargs -n 2 mv
(rodem as linhas acima sem o mv do xargs para entende-las – é metaprogramação)
Agora… tudo isso é muito bonito mas… veja se o seu computador possui os comandos mmv ou rename (que facilitam Absurdamente a tarefa)
rename .txt .html *.txt
mmv "*.txt" "#1.html"
Simples, não?
Tudo depende do tempo que temos e das nossas necessidades. Mesmo que o rename/mmv sejam uteis, pode ser que a forma com awk / sed valha mais a pena pois o ls pode ser substituido por um find (ja pensou nisso?)
Na verdade, Tiago, sou um belo amador, brinco de fazer scripts como terapia.. terapia que eu realizava aos montes na época de mIRC.
Por conta mesmo do meu amadorismo, não consegui entender seu exemplo de como queimar os registros intermediários. Mas não esquente com isso, se não há aquela variável mágica que eu usava no mIRC, é melhor que eu me contente com minhas limitações. Em todo caso, fico ligado nas suas dicas da seção shell.
Infelizmente o gawk não tem o conceito de range. Quando vc utiliza o operador $X vc esta pegando o X-ésimo campo daquele registro. Vc tem uma variavel que é setada a cada registro que é NF, o numero de registros, que permite que vc leia o ultimo registro de forma simples
print $1,$NF
Agora… tem uma sacanagem que vc pode fazer: $0 é o registro inteiro, porém vc pode “queimar” alguns registros intermediarios
no seu caso, se vc fizesse
$3=$4=$5=$6=””
print $0
só sobraria o que vc quer.
Uma forma, menos agressiva, seria tentar pegar um padrão via expressões regulares.
Você parece o sujeito certo pra esclarecer um dúvida:
Se eu quiser filtrar uma string do seguinte tipo
7718 0.0 0.0 1756 476 ? Ss 17:59 0:00 /bin/sh -c pidgin
Como AWK eu posso fazer através de algo como “awk ‘{print $1,$2,$10}’”
Mas se eu quiser, por exemplo, filtrar o $1, o $2 e todos OS DEMAIS após o $7 sem saber o número total de termos, há alguma variável pra isso? Não sei se me fiz entender, mas essa dúvida me persegue desde que lembrei que quando eu brincava editando scripts no mIRC, uma simples $7- realizava essa função
Desculpe o abuso, abraços