Leia os argumentos separados por nova linha

0

Eu tenho um script e recebo dados de stdin como um argumento separado por novas linhas que dizem que tenho

string1,string2
string3,string4

E eu quero levar em muito string1,string2 e string3,string4 . Mas eu recebo um número desconhecido dessas linhas, meu script apenas lê os dois primeiros e depois para. Eu tentei analisar \n de stdin mas não funciona.Como devo abordar isso?

Eu tentei ler assim

for i in "$@" 
do 
var1=$(echo "$i" | cut -f2 -d,) 
var2=$(echo "$i" | cut-f2 -d,)
#etc

O que estou realmente tentando fazer é dizer que tenho um arquivo input.txt com esse tipo de entrada:

string1,string2
string3,string4

Se eu fizer cat input.txt | ./myscript.sh , não importa quantas linhas de strings eu tenha, eu quero pegar cada linha e extrair dela em 2 variáveis stringI,stringJ , respectivamente.

    
por C. Cristi 22.11.2018 / 08:15

3 respostas

4

Se for para processamento de texto, o mais óbvio é usar awk , que é especialmente projetado para isso (embora perl ou sed também possa ser usado)

awk -F, '{print "something with "$1" and "$2}'

Se a entrada for um CSV real que poderia ter valores mais complexos, como:

"field, with comma" , "and with
newline", "or ""quotes"""

Você pode querer usar perl ou python ou alguns utilitários de análise csv dedicados.

Se os campos tiverem que ser disponibilizados como variáveis de shell, porque por exemplo você precisa executar alguns comandos específicos com esses campos como argumentos, então você faria algo como:

while IFS=, read -r a b rest; do
   something-with "$a" "$b"
done

Veja também o GNU parallel para executar as coisas em paralelo:

PARALLEL_SHELL=sh parallel -C, 'something-with {1} {2}'

Mas cuidado, o GNU parallel traz uma sobrecarga significativa para que a paralelização valha a pena.

O shell ksh93 pode realmente entender o formato CSV (manipular citações de campos individuais, como no exemplo complexo acima)

while IFS=, read -rS a b rest; do
   do-something-with "$a" "$b"
done
    
por 22.11.2018 / 09:04
1

Eu sugiro que você possa usar a opção de leitura com -d, que usa a entrada de várias linhas do usuário.

ou use tr '\n' ' ' para traduzir nova linha para o espaço. Isso é hacky.

Eu não conheço o caminho, mas você pode usar o tr para traduzir o EOF para a nova linha para que ele seja perfeito na sua expectativa.

sinta-se à vontade para comentar se precisar de mais detalhes.

    
por 22.11.2018 / 09:31
0

Se (por algum motivo) você quiser colocar todas as linhas de entrada em um array, no bash você usa

readarray -t input_lines

e, em seguida, cada linha é armazenada como um elemento da matriz indexada input_lines . O -t é retirar a nova linha de cada linha.

    
por 22.11.2018 / 15:21