Question

I have a bunch of files named jtn216_<n>.o<m> where n and m are integer. The first one is assigned by me and the second one by the system. I need to check the last line at each file. I ran this to split that line into array

for i in {361..380}; do 
  v=$(tail -n 1 jtn216_$i.o*)
  IFS=' ' read -ra line <<< "$v"
  echo $line $v 
done

3499200 3499200 87650.5574975270 13.6931802555886
1014400 1014400 87947.4382620423 13.9208064005841
3475800 3475800 87779.1695691355 13.8939964916376
3479200 3479200 87459.7284508034 13.7824644675699
3827800 3827800 87868.7538056652 13.8792123626210
2551600 2551600 87615.6417285010 13.8700006744178
3818400 3818400 87872.1788028955 13.8942371285402
3476800 3476800 87842.0543708163 13.9170342642747
3481800 3481800 87670.5841054385 13.8808556469308
2559200 2559200 87800.6530231416 13.8874423695824
3841600 3841600 87804.3972028423 13.8657419719638
916400 916400 87776.1342228681 13.8622746230494
3839000 3839000 87662.8185016707 13.8576498806465
3835200 3835200 87933.6917697832 14.0007327053153
3482000 3482000 88323.3509854563 13.9453990979062
3485400 3485400 87657.5078357100 13.8478805156354
3484800 3484800 87757.3379321554 13.8215034461609
3475400 3475400 87970.4729449120 13.9605031841208
3481800 3481800 87612.4211302676 13.8327950845915
2319400 2319400 87521.5669854330 13.8383953325475

I expected line to be an array not the first value from v. What am I doing wrong?

Was it helpful?

Solution

I think you're just printing line wrongly. Try echo "${line[@]}" instead.

OTHER TIPS

You should address the contents of the array variable $line well e.g.

echo "${line[0]}"
echo "${line[*]}"  # converts to a single string
echo "${line[@]}"  # converts to multiple elements i.e. multiple arguments for echo

When an array variable is addressed without an index it would be just equivalent to getting the first element.

What bash calls "arrays" are really just a list of words (a list that can't even be nested). So if you simply output the array using echo, you're just asking it to output a list of arguments to echo. Consider:

echo foo bar # 'foo bar\n'
echo -n foo bar # 'foo bar'
x=( -n foo bar )
echo "${x[@]}" # 'foo bar'

If you output an array's name without any index or @ or * component, you will get the first word* in that array:

echo "$x" # foo

So when you do echo $line $v what you're really saying is

echo ${line[0]} $v

Here's what you probably want:

for i in {361..380}; do 
  tail -n 1 jtn216_$i.o* | { # Pipe to a compound command to preserve assignments from read
    IFS=' ' read -ra line
    printf '[ '
    printf '%s ' "${line[@]}"
    printf ']\n'
  }
done

Then you should see

[ 3499200 87650.5574975270 13.6931802555886 ]
[ 1014400 87947.4382620423 13.9208064005841 ]
[ 3475800 87779.1695691355 13.8939964916376 ]
…

*Wordsplit again since you didn't use quotes.

Try the following, if you want to get last line as array:

v=(`tail -n 1 jtn216_$i.o*`)

UPDATED

To accumulate line as array use:

v=(`tail -n 1 jtn216_$i.o*`)
line+=(${v[@]})

To output whole array:

${line[@]} or ${line[*]}

To count number of array elements:

${#line[@]} or ${#line[*]}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top