Awk para saída de arquivo de leitura

2

Ainda não entrei em awk , mas está na minha disposição aprender este ano. Eu fiz uma pergunta anterior que me levou a awk e funciona. No entanto, não tenho certeza de como inserir todos os tipos de arquivo e gerar o tipo de arquivo com o nome exato em awk . Exemplo:

  • localiza todos os arquivos .xml
  • localiza file.xml
  • o awk script
  • salvo como file.xml

Eu pesquisei awk no bash e descobri este mas eu não acho que isso vai resolver o problema da impressão atual do código awk de volta para um arquivo .xml . Para eu atualmente executar o script, tenho que fazer gawk -f file.sh < file.xml .

Meu objetivo seria pesquisar todos os arquivos .xml , executar código e salvar no mesmo local o novo arquivo .xml .

EDITAR: Consegui recuperá-lo para o xml depois de mais algumas buscas com isso:

gawk -f awk.sh < file.xml > file.xml
    
por DᴀʀᴛʜVᴀᴅᴇʀ 18.12.2012 / 17:34

2 respostas

3

Se você não se importar em usar outra ferramenta, investigue também o comando find , em particular a opção -exec, ou combine-a com o comando xargs . (Também investigar find ... -print0 | xargs -0 ... )

    
por 18.12.2012 / 17:40
0

Você tem vários problemas para resolver.

No mínimo, você terá que fornecer ao seu script AWK uma lista de arquivos, pois ele não possui uma maneira integrada de pesquisar diretórios. Isso pode ser feito da maneira mais fácil e óbvia pelo shell ou por find . Existem várias maneiras diferentes de entregar a lista ao AWK também.

Você também terá que tomar cuidado para substituir apenas o arquivo original se o script tiver processado com êxito o conteúdo e salvado a saída em um arquivo temporário.

Você também terá que pensar muito sobre o que você está tentando fazer com esses arquivos XML. XML (e todos os "idiomas" similares a SGML) tem uma sintaxe atrozmente difícil de analisar.

Se você começar com o último problema primeiro e conseguir criar um script simples que será efetivamente um programa de filtragem que processará um arquivo de entrada dado a ele na entrada padrão, gravando os resultados na saída padrão, você terá resolvido o problema. passo mais importante, e você pode testá-lo simplesmente com o redirecionamento de arquivos na linha de comando, como você adivinhou, mas você terá que ser extremamente cuidadoso para não sobre-escrever ou truncar seus arquivos de entrada:

awk -f script.awk < input_file > output_file

Um pouco de sintaxe de shell ajudará você a transformar o arquivo de entrada renomeando o arquivo de saída para o mesmo nome que o script obtém (resolvendo assim o segundo problema):

awk -f script.awk < input_file > output_file && mv output_file input_file

O comando após o && só será executado se o comando antes de ser executado e sair com um status de sucesso (um código de saída de 0 .

Agora você pode finalmente resolver o primeiro problema de lidar com um grande número de arquivos. A maneira mais simples de iterar os comandos acima em uma lista de arquivos seria usar um pequeno loop de shell que lê um nome de cada vez e o processa usando o comando acima:

while read fn; do
    awk -f script.awk < "${fn}" > "${fn}.out" && mv "${fn}.out" "${fn}" || break
done

O || break fará com que o loop seja encerrado se o processo awk falhar, deixando um arquivo .out parcial para o arquivo com falha. Observe também as citações cuidadosas das expansões de variáveis - isso garante que os nomes de arquivos que contêm espaços em branco sejam corretamente manipulados.

Agora que while read loop irá, é claro, apenas esperar que você digite um nome de arquivo, depois outro, etc., até que você o interrompa ou envie um caractere EOF. Então, simplesmente você poderia alimentá-lo com uma lista de nomes de arquivos usando find , assim:

find . -name '*.xml' -print | while read fn; do

....

Você pode incluir tudo isso em um pequeno script ou apenas digitá-lo na linha de comando.

Se você fizer um pequeno script de shell, então poderá alternadamente fazer com que o loop while faça uma iteração na lista de parâmetros da linha de comando e tratar cada um como um nome de arquivo para processar. Dessa forma, você poderia usar a expansão de nome de arquivo do shell para gerar a lista de arquivos a serem processados, como é típico de muitos programas unix que processam listas de arquivos fornecidos na linha de comando. Você usaria um loop for assim:

for fn
do

....

(Note que não há ponto-e-vírgula após o nome da variável na primeira linha!)

Você também pode modificar seu script AWK para ler uma lista de nomes de arquivos a partir da entrada padrão e renomear o próprio arquivo de saída usando a função system() para chamar mv .

    
por 01.01.2013 / 02:52

Tags