Creating array from file

Dear community,
how can I create an array from file taking only the 4th field?

out.txt file is something like this:

1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20

So the final array should be:

4 8 12 16 20

With this command I created an array with all the fields, but I need only the 4th one:

arr1=( $(cat out.txt | tr '\n' ' ') )

You are not specifying what shell you use; looks like it's bash; try

$ arr=( $(cut -d" " -f4 test) )
$ echo ${#arr[@]} , ${arr[@]}
5 , 4 8 12 16 20

Yes bash, but the command doesn't work for me :frowning:

#!/bin/bash
arr=( $(cut -d" " -f4 out.txt) )  
echo ${arr[@]}   

result empty array:

# ./test.sh 

# 

---------- Post updated at 02:59 PM ---------- Previous update was at 02:55 PM ----------

Aaah wait, this because I've not specify the correct out.txt file:

So I have as out.txt:

1234567890 1 1 9876[9876=1]
7634567890 1 1 3456[3456=1]
8934567890 1 4 0123[0123=1];1234[4567=3]
5534567890 1 1 0001[0101=1]
7834567890 1 1 3256[3256=1]
4534567890 1 1 7560[7560=1]
1334567890 1 1 900[0900=1]
0034567890 1 2 9899[9899=2]

And this out.txt file with your command produce an empty array! :frowning:

Pls try the cut cmd from the keyboard, as well as the echo, and post the results.

your new out.txt:

echo ${arr[@]}
9876[9876=1] 3456[3456=1] 0123[0123=1];1234[4567=3] 0001[0101=1] 3256[3256=1] 7560[7560=1] 900[0900=1] 9899[9899=2]

In bash you can use mapfile:

mapfile -t myarray < <(cut -d" " -f4 file)

--
Bye

The cut commnad reply me with blank space:

cut -d" " -f4 out.txt

















#

Try with -f1, -f2, -f3

OR: provide an octal/hexdump of out.txt

You probbly have more than 1 space between each field, try using awk instead of cut:

arr=( $(awk '{ print $4}'  out.txt)
echo ${arr[@]}
1 Like

Of course: if you load the array in a subshell (scripts are run in subshells), how can you have it in the parent shell?
------- EDIT ------------------------------
Sorry, I misread your message: I thought you were running echo outside the script.
--
Bye

Oh YES!!! More space between fields!!! :b:
Your command works ok, except for the fact you've missed one ')' :wink:

arr=( $(awk '{ print $4}'  out.txt) )
echo ${arr[@]}

Thanks all for partecipating! Apreciated! :wink:

---------- Post updated at 04:04 PM ---------- Previous update was at 03:12 PM ----------

Guys sorry, whitout opening a new thread, is it possible to put into an array the whole line?

1234567890 1 1 9876[9876=1]
7634567890 1 1 3456[3456=1]
8934567890 1 4 0123[0123=1];1234[4567=3]
5534567890 1 1 0001[0101=1]
7834567890 1 1 3256[3256=1]
4534567890 1 1 7560[7560=1]
1334567890 1 1 900[0900=1]
0034567890 1 2 9899[9899=2]

So the array will be:

arr[0]="1234567890 1 1 9876[9876=1]"
arr[1]="7634567890 1 1 3456[3456=1]"
arr[2]="8934567890 1 4 0123[0123=1];1234[4567=3]"
....
....

Then later I'll take the 4th value and the other one to post-process them....

To put into an array the whole lines of a file:

mapfile -t myarray <file

help mapfile for details.
--
Bye

Note mapfile requires bash 4 is you are still on 3 you may need to use cat:

OLDIFS=$IFS
IFS=$'\n'
arr=( $(cat out.txt) )
IFS=$OLDIFS
1 Like

It may not be an issue for this data set, but, just in case, I'll mention that this approach deletes newlines since contiguous IFS whitespace is treated as a single delimiter.

If the situation requires preserving lines (including newlines) exactly as they appear in the text file, the following will do it:

while IFS= read -r line; do
    arr[${#arr[@]}]=$line;
done

Regards,
Alister

1 Like

Thanks all for partecipating, I'll keep all your suggestion for future use! :wink:

For now, I'll create 4 array for each row in the output file. This will simplify my post-processing!

:b:

Just a question, if I can, mapfile is not present in my bash. This because probably I don't have bash v4.
How can I upgrade to bash v4 ??