Como usar comandos que funcionam apenas com um arquivo por vez com todos os arquivos que você selecionar

Muitas vezes precisamos executar um script para converter um pdf em texto, converter os arquivos .doc em html, etc; o ponto é que esses comandos aceitam apenas um arquivo por vez e isso é muito enfadonho para nós se precisamos realizar a mesma tarefa em vários arquivos, especialmente quando fazemos um script.

Proponho uma solução para este problema usando ls, sede, grep, awk y sh. O que faremos é criar a linha de comando correta em cada linha e executá-los com sh, e como sh executará uma linha por vez, o consumo de memória RAM não aumentará, o que com outros métodos pode até mesmo congelar máquinas com baixa potência.

Vamos ver como realizar esta seqüência de comando.

1- A primeira coisa que temos que fazer é apresentar os arquivos que serão usados ​​por meio ls:

ls --directory /camino/a/carpeta/*.ext

2- Então, precisaremos desses arquivos para passar as cotações «/ caminho / para grupo de
arquivos«

ls --directory /camino/a/carpeta/*.ext | sed 's/^/"/' | sed 's/$/"/'

3- Agora awk ele estará pronto para receber os dados.

ls --directory /camino/a/carpeta/*.ext | sed 's/^/"/' | sed 's/$/"/' | awk '{print $0}'

Devido a que awk tem a sua própria linguagem teremos de separar as aspas que queremos que apareçam para citar um texto entre outras funções teremos de usar a barra invertida \ Vamos ver como separar alguns.
Separe uma citação

\”

Mostra uma barra invertida na saída (precisaremos digitar três barras)

\\\

Às vezes, precisaremos de um separador de isolamento, apenas o texto ou as aspas que aparecem entre as duas barras invertidas serão geradas na saída:

'""'\"\'""'

4- Vamos ver como renomear todos os arquivos listados usando o comando mv apenas para inserir um sufixo. (Agora, para listar o arquivo, precisaremos usar a combinação "$ 0" sempre que precisarmos usá-la)

ls --directory /camino/a/carpeta/*.ext | sed 's/^/"/' | sed 's/$/"/' | awk '{print "mv "$0" \"`dirname

"$ 0 ″" / Text-any-`basename "$ 0 ″" \ ""} '| sh

Nota é adicionada no final, conforme mostrado na sequência anterior, a combinação « | eh »Que redireciona o pipeline para este interpretador de comando

Vejamos alguns exemplos preparados para criar um script.

Ejemplos:

1- Converta todos os PDFs listados em arquivos de texto.

ls --directory “$@” | sed 's/^/"/' | sed 's/$/"/' | awk '{print "pdftotext",$0}' | sh

Nesse caso, não é necessário selecionar um arquivo de saída, pois o pdftotext gera automaticamente um arquivo de texto com o nome base e a isenção .txt se e somente se você estiver trabalhando com um único arquivo.

2- Digamos que queiramos aplicar um efeito a uma imagem mas sem modificar o original, vamos ver um exemplo com o efeito de onda bem conhecido pelo logotipo do Windows XP, pois é uma bandeira com efeitos ondulados (para melhor apreciar este efeito, é recomendado para usar como imagem resultante com a extensão .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: vários passes são feitos nesta sequência:

  • Um para obter a pasta onde o arquivo está localizado com dirname
  • Outro para obter o nome de base, mas retirando a extensão do referido arquivo
  • Outra para obter a isenção do referido arquivo.

3- Agora vamos ver como renomear um grupo de arquivos colocando o número correspondente antes do nome (sufixo numérico).

ls --directory “$@” | sed 's/^/"/' | sed 's/$/"/' | awk '{print FS="mv "$0" '""'\"\'""'`dirname
"$0"`/"FNR"-`basename "$0"`'""'\"\'""' "}' | sh

Para inserir o número, foi utilizado o idioma awk interno com a opção “FNR” que relaciona cada linha de saída, de forma que o número pode ser colocado antes ou depois do texto.

Vamos ver como colocar um prefixo numérico (colocar um número no final, mas antes da isenção) esta opção só é válida se o arquivo possuir um.

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- Vejamos um exemplo onde teremos que inserir dados ou selecionar um grupo de funções, tomando como exemplo o caso em que removemos a proteção por senha de vários arquivos PDF que possuem a mesma senha. (Neste caso, usaremos o Zenity como uma caixa 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

Dependendo da versão do zenity, a opção de senha pode ser apenas –pasword.

Como você viu, o objetivo é fazer um gato de um arquivo que será criado no início da linha apenas uma vez e será excluído assim que a conversão for concluída.

5- Outro utilitário é, quando precisamos descompactar vários arquivos compactados em .zip

ls --directory “$@” | sed 's/^/"/' | sed 's/$/"/' | awk '{print "unzip -x "$0" "}' | sh

As aspas extras devem ser separadas por um espaço onde a opção "$ 0" é usada.
Exemplo
"unzip -x "$0" "

6- Vamos ver um exemplo para proteger um pdf com uma senha que permite a leitura, mas protegido contra cópia de impressão ou outras opções, (as opções listadas na caixa de diálogo serão aquelas que serão permitidas no pdf, se você não quiser permitir nenhuma e selecione nenhum).

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

Com estes exemplos é bastante exemplificado como usar esta opção para converter, modificar ou renomear vários arquivos com um único script e não convertê-los manualmente um a um. O consumo de memória com esta opção é mínimo, dependendo do comando que está sendo utilizado, já que não os converte ao mesmo tempo e sim um após o outro.

Esta opção pode ser muito útil se quisermos converter um grupo inteiro de vídeos com o mencoder sem que este os junte em um; você pode preparar um script para isso e eles apenas teriam que colocar ls --directory %F | sed 's/^/"/' | sed 's/$/"/' | awk '{print "script-convertir-video "$0" "}' | sh && zenity --info --text "Todas las conversiones han terminado"

FIM


Deixe um comentário

Seu endereço de email não será publicado. Campos obrigatórios são marcados com *

*

*

  1. Responsável pelos dados: Miguel Ángel Gatón
  2. Finalidade dos dados: Controle de SPAM, gerenciamento de comentários.
  3. Legitimação: Seu consentimento
  4. Comunicação de dados: Os dados não serão comunicados a terceiros, exceto por obrigação legal.
  5. Armazenamento de dados: banco de dados hospedado pela Occentus Networks (UE)
  6. Direitos: A qualquer momento você pode limitar, recuperar e excluir suas informações.

  1.   Ramiro dito

    Não seria muito, mas MUITO mais fácil de fazer tudo isso usando expressões regulares ou curingas? Não entendo qual é a diferença entre isso e tornar sua vida tão complicada com isso.

  2.   crotus dito

    A verdade é que você tem um grande conhecimento dos comandos do Linux. Muito útil!

    1.    KZKG ^ Gaara dito

      Sim, sei que vamos aprender muito com ele por aqui hahaha.

  3.   hexborg dito

    Acho que é muito mais fácil:

    ls -d /path/to/folder/*.ext | enquanto lê o arquivo; faça o COMMAND "$ file"; feito

    Em vez de COMMAND, você pode colocar o que quiser e funcionará mesmo que os arquivos contenham espaços em branco, desde que você coloque $ file entre aspas. Você não precisa usar o sed para isso ou gerar os comandos com awk. Além disso, isso inicia menos processos.

    1.    Ankh dito

      o:
      para i em $ (ls -d /path/a/folder/*.ext); faça o COMANDO “$ i”; feito;

      1.    hexborg dito

        Parece bom, mas se os nomes dos arquivos contiverem espaços em branco, não funcionará. 🙂

        1.    tahed dito

          Na verdade, hexborg é o motivo pelo qual o texto de saída é citado no início e no final de cada linha com esta opção:
          ls –diretório | sed 's / ^ / »/' | sed 's / $ / »/'

          Esclareço que find pode ser usado para pesquisar os subdiretórios.

          1.    hexborg dito

            Mas com meu truque você não precisa. ls retira os nomes completos dos arquivos, um em cada linha, lê as leituras linha por linha e deixa o nome do arquivo na variável de arquivo, quer tenha espaços em branco ou não. Você só precisa colocar $ file entre aspas ao usá-lo no comando.

          2.    Hugo dito

            Concordo que em encontrar pode ser menos complicado. Vamos pegar este exemplo do artigo:

            ls --directory “$@” | sed 's/^/"/' | sed 's/$/"/' | awk '{print "pdftotext",$0}' | sh

            O mesmo poderia ser alcançado assim, e provavelmente será executado mais rápido:

            find . -type f -print0 | xargs -0 pdftotext

            Dito isso, o artigo é bem-vindo, é sempre bom aprender sobre formas alternativas de fazer algo.

        2.    Ankh dito

          Se você notar que $ i está entre aspas. Isso torna desnecessário o escape de espaços em branco.

          1.    hexborg dito

            Sim, mas o operador $ () expande os nomes dos arquivos sem colocar aspas em nenhum lugar, então a variável i já captura os nomes dos arquivos cortados. Experimente em um terminal em um diretório que contenha arquivos com espaços nos nomes.

  4.   Leão dito

    Muito bom, complexo, mas muito interessante.

  5.   helena_ryuu dito

    isso é incrível, ótimo !!!!

  6.   msx dito

    Excelente, a plasticidade do GNU / Linux não tem limites.

  7.   Natália dito

    Caro blogueiro,

    Sou Natalia, gerente de comunicações do Paperblog. Depois de descobri-lo, estou entrando em contato com você para convidá-lo a conhecer o projeto Paperblog, http://es.paperblog.com, um novo serviço de jornalismo cidadão. Paperblog é uma plataforma digital que, como uma revista de blog, publica os melhores artigos dos blogs cadastrados.

    Se o conceito lhe interessa, basta propor seu blog para participar. Os artigos seriam acompanhados de seu nome / pseudônimo e arquivo de perfil, além de diversos links para o blog original, no início e no final de cada um. Os mais interessantes podem ser selecionados pela equipe para aparecer na página de rosto e você pode ser selecionado como o autor do dia.

    Espero que você esteja motivado pelo projeto que iniciamos com tanto entusiasmo em janeiro de 2010. Dê uma olhada e não hesite em me escrever para mais detalhes.

    Receba uma saudação cordial e afetuosa,
    Natália