0

I am trying to store the contents of a .txt file in two sets of arrays in bash. The file is a list of characteristics for given data files, delimited by vertical bars (|). So far, I have written code that reads the file and prints each line of data separately, each followed by the given sections of the line.

#prints line of text and then separated version
while IFS='' read -r line || [[ -n "$line" ]]
do
    echo "Text read from file: $line"
 words=$(echo $line | tr "|" "\n")
 for tests in $words 
 do 
  echo "> $tests"
 done
done < "$1"

Example output:

Text read from file: this|is|data|in|a|file
> this
> is
> data
> in
> a
> file
Text read from file: another|example|of|data
> another
> example
> of
> data

Is there a way for me to store each individual line of data in one array, and then the broken up parts of it within another? I was thinking this might be possible using a loop, but I am confused by arrays using bash (newbie).

1

1 Answer 1

1

OK -- I just read in the lines like you have done, and append them to the lines array. Then, use tr as you have done, and append to the words array. Just use the parentheses to mark them as array elements in the assignments:

$ cat data.txt
this|is|data|in|a|file
another|example|of|data

$ cat read_data.sh 
#!/bin/bash
declare -a lines
declare -a words
while IFS='' read -r line || [[ -n "$line" ]]
do
    echo "Text read from file: $line"
    lines+=( $line )
    words+=( $(echo $line | tr "|" " ") )
done < "$1"

for (( ii=0; ii<${#lines[@]}; ii++ )); do
    echo "Line $ii ${lines[ii]}"
done

for (( ii=0; ii<${#words[@]}; ii++ )); do
    echo "Word $ii ${words[ii]}"
done

$ $ ./read_data.sh data.txt 
Text read from file: this|is|data|in|a|file
Text read from file: another|example|of|data
Line 0 this|is|data|in|a|file
Line 1 another|example|of|data
Word 0 this
Word 1 is
Word 2 data
Word 3 in
Word 4 a
Word 5 file
Word 6 another
Word 7 example
Word 8 of
Word 9 data
Sign up to request clarification or add additional context in comments.

3 Comments

You could also do words using bask substitution: words+=( ${line//|/ } )
Awesome! Thanks so much. I'm having some issues with my data breaking when there is a space between two characteristics (within the same delimeters). For example: |2017-06-20 11:16:39.103| splits into two "Word" and "Line" indexes. Any tips for how to avoid this other than deleting the space between the two characteristics?
Yes. Since the field delimiter is a pipe, swap pipes with spaces: words+=( $(echo $line | tr "| " " |") ). Now, the words that had spaces will have pipes. In the loop that shows the words, add this line to change the pipes back to spaces (per grail's suggestion): words[ii]="${words[ii]//|/ }"

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.