0

I am writing a Bash Shell script, which reads a bunch of lines from a file, and tries to append each line to an array, thus:

# counter variable    
i=0

cat doc.txt | while read -r line; do
    myArr[i]="$line"
    ((i=i+1))
done

The file doc.txt contains one word in every line. When I print the array (through echo ${myArr[@]} or for x in ${myArr[@]};do echo $x; done), my array seems to be empty. What am I doing wrong? Thanks!

Edit: I also tried doing this in Ksh, with the same results. An answer in either Bash or Ksh is acceptable, since I seem to be having the same issue in both.

lebowski
  • 1,031
  • 2
  • 20
  • 37
  • 2
    Are you sure you are using `ksh`? In `bash`, for instance, the `while` loop runs in a subprocess, which means `myArr` isn't modified in the shell that runs the pipeline. Try `while read -r line; do ...; done < doc.txt`. – chepner Dec 05 '17 at 17:08
  • The notorious `cat file | cmd`... Either use redirection suggested by @chepner or use `shopt -s lastpipe` before the loop (redirection is much better). – PesaThe Dec 05 '17 at 17:17
  • 1
    And [BashFAQ/024](http://mywiki.wooledge.org/BashFAQ/024) – Benjamin W. Dec 05 '17 at 17:21
  • Which specific version of ksh did you get the same result in? Unlike bash, ksh *does* (typically) run the last component of a pipeline in the same shell that was running the script previously. (Not that you should be using `cat file` at all -- ` – Charles Duffy Dec 05 '17 at 17:37
  • Also, are you attempting to execute the script, *then* check the contents of the array? That won't work for the same reason `cat | while` would fail; you are setting the array in a separate process than the one in which you look at the array. – chepner Dec 05 '17 at 17:45
  • @chepner No, I am trying to print through the same script. – lebowski Dec 05 '17 at 17:53

1 Answers1

2

You are running the while loop in a subshell, so any changes you make to the array disappear once that shell exits. Use input redirection instead:

while IFS= read -r line; do
    myArr+=("$line")
done < doc.txt

If you using bash 4.0 or later, you can use a single command

readArray -t myArr < doc.txt
chepner
  • 497,756
  • 71
  • 530
  • 681