Moitas veces necesitamos executar un script para converter un pdf en texto, converter os ficheiros .doc en html, etc; a cuestión é que estes comandos só aceptan un ficheiro á vez e iso é moi tedioso para nós se necesitamos realizar a mesma tarefa en varios ficheiros, especialmente cando facemos un script.
Propoño unha solución para este problema usando ls, sed, grep, vaia y sh. O que faremos é crear a liña de comandos correcta en cada fila e executalas con sh, e dado que sh executará unha liña á vez, o consumo de memoria RAM non aumentará, o que con outros métodos pode incluso conxelar máquinas con pouca potencia.
Vexamos como levar a cabo esta secuencia de comandos.
1- O primeiro que temos que facer é presentar os ficheiros que se empregarán ls:
ls --directory /camino/a/carpeta/*.ext
2- Despois necesitaremos estes ficheiros para pasar comiñas «/ camiño / ao grupo de
arquivos«
ls --directory /camino/a/carpeta/*.ext | sed 's/^/"/' | sed 's/$/"/'
3- Agora vaia estará listo para recibir os datos.
ls --directory /camino/a/carpeta/*.ext | sed 's/^/"/' | sed 's/$/"/' | awk '{print $0}'
Porque vaia ten a súa propia lingua teremos que separar as comiñas que queremos que aparezan para citar un texto entre outras funcións teremos que empregar a barra invertida \ Vexamos como separar algúns.
Separe unha cotización
\”
Mostrar unha barra invertida na saída (teremos que escribir tres barras)
\\\
Ás veces necesitaremos un separador illante, só sairá na saída o texto ou as comiñas que aparecen dentro das dúas barras invertidas:
'""'\"\'""'
4- Vexamos como renomear todos os ficheiros listados usando o comando mv só para introducir un sufixo. (Agora para listar o ficheiro teremos que empregar a combinación "$ 0" sempre que o necesitemos)
ls --directory /camino/a/carpeta/*.ext | sed 's/^/"/' | sed 's/$/"/' | awk '{print "mv "$0" \"`dirname
"$ 0 ″" / Text-any-`basename "$ 0 ″" \ ""} '| sh
A nota engádese ao final como se mostra na secuencia anterior a combinación « | sh »Que redirecciona a canalización a este intérprete de comandos
Vexamos algúns exemplos preparados para crear un script.
Exemplos:
1- Converte todos os pdf que se listan en ficheiros de texto.
ls --directory “$@” | sed 's/^/"/' | sed 's/$/"/' | awk '{print "pdftotext",$0}' | sh
2- Digamos que queremos aplicar un efecto a unha imaxe pero sen modificar o orixinal, vexamos un exemplo co efecto de onda ben coñecido polo logotipo de Windows XP, xa que é unha bandeira con efectos ondulados (para mellor apreciar este efecto é recoméndase usar como imaxe resultante coa extensión .png).
ls --directory “$@” | sed 's/^/"/' | sed 's/$/"/' | awk '{print FS="convert -wave 25x150
"$0"","\"\`dirname "$0"`/`basename "$0" | sed '"'"s/\\\\.[[:alnum:]]*$//"'"'`-wave.`basename "$0" |
rev | awk -F . \'"'"'\{print $1}\'"'"'\ | rev`'""'\"\'""' "}' | sh
Nota: fanse varios pases nesta secuencia:
- Un para obter o cartafol onde se atopa o ficheiro con dirname
- Outro para obter o nome base, pero eliminando a extensión do devandito ficheiro
- Outro para obter a exención de dito expediente.
3- Vexamos agora como renomear un grupo de ficheiros poñendo o número correspondente diante do nome (sufixo numérico).
ls --directory “$@” | sed 's/^/"/' | sed 's/$/"/' | awk '{print FS="mv "$0" '""'\"\'""'`dirname
"$0"`/"FNR"-`basename "$0"`'""'\"\'""' "}' | sh
Vexamos como poñer un prefixo numérico (poña un número ao final, pero antes da exención) esta opción só é válida se o ficheiro ten un.
ls --directory “$@” | sed 's/^/"/' | sed 's/$/"/' | awk '{print FS="mv "$0" \"`dirname
"$0"`/`basename "$0" | sed '\'s/\\\\.[[:alnum:]]*$//\''`-"FNR".`echo "$0" | rev | awk -F .
'""'\'\'""'{print $1}'""'\'\'""' | rev `\" " }' | sh
4- Vexamos un exemplo no que teremos que introducir datos ou seleccionar un grupo de funcións, tomando como exemplo o caso no que eliminamos a protección por contrasinal de varios ficheiros pdf que teñen o mesmo contrasinal. (Neste caso usaremos zenity como un cadro de diálogo)
zenity --entry --hide-text --text "introduzca la clave de desbloqueo" > $HOME/.cat && ls
--directory “$@” | sed 's/^/"/' | sed 's/$/"/' | awk '{print FS="pdftk "$0" input_pw `cat
$HOME/.cat` output \"`dirname "$0"`/`basename "$0" .pdf`-unlock.pdf\" "}' | sh && rm
$HOME/.cat
Como viches, o obxectivo é facer un gato dun ficheiro que se creará ao comezo da liña só unha vez e que se eliminará unha vez finalizada a conversión.
5- Outra utilidade é cando necesitamos descomprimir varios ficheiros compactados en .zip
ls --directory “$@” | sed 's/^/"/' | sed 's/$/"/' | awk '{print "unzip -x "$0" "}' | sh
Exemplo
"unzip -x "$0" "
6- Vexamos un exemplo para protexer un pdf cun contrasinal, permitindo a lectura pero protexido contra a impresión de copias ou outras opcións (as opcións listadas no cadro de diálogo serán as que se permitirán no pdf, se non quere permitir ningunha deles, non seleccione ningún).
zenity --separator " " --multiple --text "Seleccione los Opciones que quiere permitir" --column "Opciones" --list "Printing" "DegradedPrinting" "ModifyContents" "CopyContents" "ScreenReaders" "ModifyAnnotations" "AllFeatures" > $HOME/.cat && zenity --entry --hidetext --text "Teclee la contraseña de protección" > $HOME/.cat2 && ls --directory "$@" | sed 's/^/"/' | sed 's/$/"/' | awk '{print FS="echo \"pdftk \\\"`echo "$0"`\\\" output \\\"`dirname "$0"`/`basename "$0" .pdf`-locked.pdf\\\" allow `cat $HOME/.cat` owner_pw \"`cat $HOME/.cat2`\"\" | sh "}' | sh && rm $HOME/.cat $HOME/.cat2
Con estes exemplos exemplifícase bastante como usar esta opción para converter, modificar ou renomear varios ficheiros cun único script e non convertelos manualmente un por un. O consumo de memoria con esta opción é mínimo, dependendo do comando que se estea a usar, xa que non os converte ao mesmo tempo senón un tras outro.
ls --directory %F | sed 's/^/"/' | sed 's/$/"/' | awk '{print "script-convertir-video "$0" "}' | sh && zenity --info --text "Todas las conversiones han terminado"
FIN
15 comentarios, deixa os teus
Non sería moito, pero MOITO máis doado facer todo isto usando expresións regulares ou comodíns? Non entendo cal é a diferenza entre iso e complicar a túa vida con isto.
A verdade, ten un gran coñecemento dos comandos Linux. Moi útil!
Si, sei que aprenderemos moito con el por aquí jajaja.
Creo que isto é moito máis doado:
ls -d /path/to/folder/*.ext | mentres se le o ficheiro; facer COMANDO "$ ficheiro"; feito
En lugar de COMMAND podes poñer o que queiras e funciona aínda que os ficheiros conteñan espazos en branco sempre que poñas $ file entre comiñas. Non precisa usar sed para iso nin xerar os comandos con awk. Tamén lanza menos procesos.
o:
para i en $ (ls -d /path/a/folder/*.ext); fai COMANDO "$ i"; feito;
Parece bo, pero se os nomes dos ficheiros conteñen espazos en branco, non funciona. 🙂
De feito, hexborg é por iso que o texto de saída cítase ao principio e ao final para cada liña con esta opción:
ls –directorio | sed 's / ^ / »/' | sed 's / $ / »/'
Aclaro que o find pode usarse para buscar nos subdirectorios.
Pero co meu truco non fai falta. Ls leva os nomes completos dos ficheiros un en cada liña e le le liña por liña e deixa o nome do ficheiro na variable do ficheiro, teña ou non espazos en branco. Só precisa poñer comiñas ao redor de $ file ao usalo no comando.
Estou de acordo en que atopalo pode ser menos engorroso. Tomemos este exemplo do artigo:
ls --directory “$@” | sed 's/^/"/' | sed 's/$/"/' | awk '{print "pdftotext",$0}' | sh
Poderíase facer o mesmo así e probablemente funcionará máis rápido:
find . -type f -print0 | xargs -0 pdftotext
Dito isto, o artigo é benvido, sempre é bo aprender sobre formas alternativas de facer algo.
Se notas que o $ i está entre comiñas. Iso fai innecesario escapar do espazo en branco.
Si, pero o operador $ () amplía os nomes dos ficheiros sen poñer comiñas en ningures, polo que a variable i xa colle os nomes dos ficheiros cortados. Próbao nun terminal dun directorio que conteña ficheiros con espazos nos nomes.
Moi bo, complexo, pero moi interesante.
isto é incrible, estupendo !!!!
Excelente, a plasticidade de GNU / Linux non ten límites.
Estimado blogueiro,
Son Natalia, Xerente de Comunicacións de Paperblog. Despois de descubrilo, estou a poñerme en contacto contigo para convidarte a coñecer o proxecto Paperblog, http://es.paperblog.com, un novo servizo de xornalismo cidadán. Paperblog é unha plataforma dixital que, como unha revista de blogs, publica os mellores artigos dos blogs rexistrados.
Se o concepto che interesa, só tes que propoñer o teu blog para participar. Os artigos irían acompañados do seu nome / pseudónimo e ficheiro de perfil, así como de varias ligazóns ao blog orixinal, ao comezo e ao final de cada un. Os máis interesantes poden ser seleccionados polo equipo para que aparezan na Portada e pode ser seleccionado como Autor do día.
Espero que estea motivado polo proxecto que comezamos con tal entusiasmo en xaneiro de 2010. Bota unha ollada e non dubide en escribirme para máis detalles.
Reciba un cordial e agarimoso saúdo,
Natalia