0

I have a script and I receive data from stdin as an argument separated by newlines say I have

string1,string2
string3,string4

And I want to take sperately string1,string2 and string3,string4. But I receive an unknown number of such lines, my script only reads the first 2 and then stops. I tried parsing \n from stdin but it does not work.How should I approach this?

I tried reading like this

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

What I am actually trying to accomplish is say I have a file input.txt with that type of input:

string1,string2
string3,string4

If I do cat input.txt | ./myscript.sh I want to take, no matter how many lines of strings I have I want to take each line and extract from it in 2 variables stringI,stringJ respectively.

C. Cristi
  • 228
  • 1
  • 4
  • 13

3 Answers3

4

If it's to do text processing, then the most obvious is to use awk which is especially designed for that (though perl or sed could also be used)

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

If the input is actual CSV which could have more complex values like:

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

You may want to use perl or python or some dedicated csv parsing utilities.

If the fields have to be made available as shell variables, because for instance you need to run some specific commands with those fields as arguments, then you'd do something like:

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

See also GNU parallel to run things in parallel:

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

But beware GNU parallel brings a significant overhead so the parallelisation has to be worth it.

The ksh93 shell can actually understand the CSV format (handle quoting of individual fields like in the complex example above)

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

I suggest you can use read with -d option which takes multi-line user input.

or use tr '\n' ' ' to translate new line to space this is hacky.

I don't know a way but you can use tr to translate EOF to new line so it will fir perfect in your expectation.

feel free to comment if you need more specifics.

Devidas
  • 507
0

If (for some reason) you want to slurp up all the input lines into an array, in bash you use

readarray -t input_lines

and then each line is stored as an element of the indexed array input_lines. The -t is to strip the newline from each line.

glenn jackman
  • 85,964