Lê linhas de um arquivo em uma variável

1

Estou tentando automatizar um processo grande para economizar tempo e esforço, e provavelmente estou tornando o processo mais difícil do que precisa ser. O que estou fazendo até agora é:

#!/bin/bash
LISTFILE="/tmp/filename"
for FILE in $LISTFILE
    do curl -XDELETE ADDRESS:PORT/VALUE/VALUE/$FILE
done

Mas não está retornando o valor para $ FILE, mas sim em / tmp e / filename. O que eu preciso fazer é percorrer o arquivo e executar o comando uma vez para cada linha e preencher o valor $ FILE.

Todas as dicas serão muito apreciadas.

    
por Eric Stillwagon 06.07.2016 / 21:13

3 respostas

3

Nesse for , você está simplesmente fazendo uma iteração em que o valor de $FILE é o valor de $LISTFILE .

Se você deseja iterar as linhas de um arquivo, use read:

while read -r FILE; do
    curl -XDELETE "ADDRESS:PORT/VALUE/VALUE/$FILE"
done < /tmp/filename

Isso pressupõe que o arquivo tenha um arquivo separado listado em cada linha.

    
por 06.07.2016 / 21:20
1

Esta linha for :

for FILE in $LISTFILE

Não significa "para cada linha em $LISTFILE ". Isso significa "para cada item na variável $LISTFILE . Seu $LISTFILE simplesmente contém o caminho do arquivo, então é isso que o $FILE estará mantendo.

Para fazer com que seu comando for repasse "cada linha do conteúdo de $LISTFILE ", você teria que alterar seu código para ficar assim:

#!/bin/bash
LISTFILE="/tmp/filename"
while read FILE
   do echo $FILE
done < $LISTFILE

Isso usa um loop while e usa o comando read , que lê 'uma entrada' linha por linha. Nossa entrada é o conteúdo do seu arquivo, que especificamos no final (esta parte: < $LISTFILE ).

    
por 06.07.2016 / 21:54
0

Em quase todos os casos em que você usa um loop for do shell para processar as linhas em um arquivo de texto, é melhor usar awk ou cut ou sed ou perl (ou qualquer as outras ferramentas de processamento de texto disponíveis). Será mais rápido, mais fácil e sem risco de efeitos colaterais indesejados (como configurar o IFS antes de usar read ).

Por exemplo:

awk '{print "curl -XDELETE '\''ADDRESS:PORT/VALUE/VALUE/"$1"'\''"}' \
 /tmp/filename | 
 sh

(execute sem tubulação para sh ou bash ou traço etc primeiro para verificar se ele produz a saída correta)

Isso faz o que você quer e envolve aspas simples em torno do URL para fornecer nomes de arquivos com espaços, curingas de glob, e comercial, ponto-e-vírgula etc. Funciona para todos os arquivos, exceto aqueles com aspas simples ou novas linhas no nome do arquivo. O último é unfixable com um arquivo de entrada separado por nova linha, mas o primeiro pode ser corrigido inserindo o seguinte antes da instrução print :

gsub(/'\''/,"'"'\\''"'");

Recentemente, escrevi uma explicação do que isso faz aqui: link

awk '{ gsub(/'\''/,"'"'\\''"'");
       print "curl -XDELETE '\''ADDRESS:PORT/VALUE/VALUE/"$1"'\''"}' \
 /tmp/filename | 
 sh

Se você estiver absolutamente certo de que não haverá caracteres irritantes nos nomes dos arquivos, é ainda mais simples:

awk '{ print "curl -XDELETE ADDRESS:PORT/VALUE/VALUE/"$1 }' /tmp/filename | sh
    
por 07.07.2016 / 09:22