How to read tab-delimited fields into an array [duplicate] - arrays

This question already has answers here:
Read tab-separated file line into array
(3 answers)
Closed 1 year ago.
I have file HOMO.txt with this content:
1506 -4.6242 2.00000
I am using below commands:
$ mapfile -t myArray < HOMO.txt
$ echo ${myArray[0]}
1506 -4.6242 2.00000
$ echo ${myArray[1]}
The last command is returning a blank line. What I want is, to assign the middle value to a variable. Can anybody please suggest a fix.

By default mapfile uses newline as element delimiter. You can change it to space " " with the -d option like follows.
mapfile -t -d " " myArray < HOMO.txt
echo ${myArray[0]}
echo ${myArray[1]}
# Output
1506
-4.6242

Related

Bash. Split text to array by delimiter [duplicate]

This question already has answers here:
How to split a string into an array in Bash?
(24 answers)
Closed 1 year ago.
Can somebody help me out. I want to split TEXT(variable with \n) into array in bash.
Ok, I have some text-variable:
variable='13423exa*lkco3nr*sw
kjenve*kejnv'
I want to split it in array.
If variable did not have new line in it, I will do it by:
IFS='*' read -a array <<< "$variable"
I assumed the third element should be:
echo "${array[2]}"
>sw
>kjenve
But with new line it is not working. Please give me right direction.
Use readarray.
$ variable='13423exa*lkco3nr*sw
kjenve*kejnv'
$ readarray -d '*' -t arr < <(printf "%s" "$variable")
$ declare -p arr
declare -a arr=([0]="13423exa" [1]="lkco3nr" [2]=$'sw\nkjenve' [3]="kejnv")
mapfile: -d: invavlid option
Update bash, then use readarray.
If not, replace separator with zero byte and read it element by element with read -d ''.
arr=()
while IFS= read -d '' -r e || [[ -n "$e" ]]; do
arr+=("$e")
done < <(printf "%s" "$variable" | tr '*' '\0');
declare -p arr
declare -a arr=([0]="13423exa" [1]="lkco3nr" [2]=$'sw\nkjenve' [3]="kejnv")
You can use the readarray command and use it like in the following example:
readarray -d ':' -t my_array <<< "a:b:c:d:"
for (( i = 0; i < ${#my_array[*]}; i++ )); do
echo "${my_array[i]}"
done
Where the -d parameter defines the delimiter and -t ask to remove last delimiter.
Use a ending character different than new line
end=.
read -a array -d "$end" <<< "$v$end"
Of course this solution suppose there is at least one charecter not used in your input variable.

bash read from file and store in array [duplicate]

This question already has answers here:
Creating an array from a text file in Bash
(7 answers)
Closed 5 years ago.
Let's say i have a file that looks like this:
element1,element2
element3,element4
element5,element6
How can I read this file in bash and store it in an array as follows:
array={element1,element2,element3,element4,element5,element6}
Can someone help me with the code? Thanks!
You can ignore read altogether and simply use redirection after setting IFS, e.g.
$ IFS=$', \t\n'; a=($(<file)); declare -p a
declare -a a='([0]="element1" [1]="element2" [2]="element3" [3]="element4" \
[4]="element5" [5]="element6")'
Instead of reading line by line, then spliting by comma, you could do:
IFS=,$'\n' read -d '' -r -a array <file
This will:
use NUL character as line delimiter (-d ''), and this way (if your file does not contain null characters) read the complete file at once
split the "line" (i.e. the complete file) in fields using IFS, which is set to comma and newline, IFS=,$'\n'
store all words/elements in array.
Output:
$ printf "%s\n" "${arr[#]}"
element1
element2
element3
element4
element5
element6
You can use this bash code:
while IFS='' read -r line || [[ -n "$line" ]]; do
array+=("$line")
done < "$1"
echo ${array[#]}
This read the content of the file that you specify by argument line and reads line by line while stores the values in a bash array.
Bye!

How to write a shell script which accepts array in the command line and outputs the sum of it [duplicate]

This question already has answers here:
How to initialize a bash array with output piped from another command? [duplicate]
(3 answers)
Closed 6 years ago.
I am new to arrays in Bash scripting. I need to write a script which accepts an array from standard input on the command line. and outputs the sum of it to the user.
Here is the logic, but how can I convert it into shell script to be used in command line?
read -a array
tot=0
for i in ${array[#]}; do
let tot+=$i
done
echo "Total: $tot"
Any help is appreciated.
You're close! Try this instead:
IFS=$'\n' read -d '' -r -a array
total=0
for i in "${array[#]}"; do
((total += i))
done
When you're reading $array from stdin with read -a, you're only getting the first line.
IFS=$'\n' changes Bash's Internal Field Separator to the newline symbol (\n) so that each line is seen as a separate field, rather than looking for tokens separated by whitespace. -d '' makes read not stop reading at the end of each line. ((total += i)) is a shorter/cleaner way to do math.
Here's it running:
$ seq 1 10 | ./test.sh
Total: 55
#!/bin/bash
calcArray() {
local total=0
for i ;do
let total+=$i
done
echo "${total}"
}
From your terminal do this source scriptName .
calcArray 1 2 3 4 5
Don't quote the args.
In your .bashrc put source scriptName, so you can always run calcArray args , without source scriptName again

Looping an array index into a screen session [duplicate]

This question already has answers here:
Bash array as argument inside of screen
(2 answers)
Closed 8 years ago.
#!/bin/bash
IFS=$'\n'
fortune_lines=($(fortune | fold -w 30))
Screen_Session=$"{mainscreen}"
Screen_OneLiner=$(screen -p 0 -S ${Screen_Session} -X stuff "`printf "say ${fortune_lines[#]}\r"`")
for var in "${Screen_OneLiner[#]}"
do
echo -e "${var}"
done
The above script only prints out line 1 one of
IFS=$'\n'
fortune_lines=($(fortune | fold -w 30))
Instead of cycling through the whole index of "fortune_lines" Not sure how to make this work.
Any ideas?
FYI
I am only using
echo -e
to troubleshoot this script.
#!/bin/bash
#OLDIFS=$IFS
IFS=$'\r'
fortune_lines=($(cat /etc/passwd | fold -w 30))
#Screen_Session=$"{mainscreen}"
Screen_Session=`screen -ls|grep "\."|grep "("|awk '{print $1}'`
Screen_OneLiner=$(screen -p 0 -S ${Screen_Session} -X stuff "`printf "say ${fortune_lines[#]}\r"`")
#IFS=$OLDIFS;
for var in "${Screen_OneLiner[#]}"
do
echo -e "${var}"
done
works fine for me I changed IFS to \r and it pumped out /etc/passwd where as with \n it only printed 1st line

How to split a multi-line string containing the characters "\n" into an array of strings in bash? [duplicate]

This question already has answers here:
How do I split a string on a delimiter in Bash?
(37 answers)
Closed 6 years ago.
I have a string in the following format:
I'm\nNed\nNederlander
I'm\nLucky\nDay
I'm\nDusty\nBottoms
I would like to move this to an array of strings line by line such that:
$ echo "${ARRAY[0]}"
I'm\nNed\nNederlander
$ echo "${ARRAY[1]}"
I'm\nLucky\nDay
$ echo "${ARRAY[2]}"
I'm\nDusty\nBottoms
However, I'm running into problems with the "\n" characters within the string itself. They are represented in the string as two separate characters, the backslash and the 'n', but when I try to do the array split they get interpreted as newlines. Thus typical string splitting with IFS does not work.
For example:
$ read -a ARRAY <<< "$STRING"
$ echo "${#ARRAY[#]}" # print number of elements
2
$ echo "${ARRAY[0]}"
I'mnNednNederla
$ echo "${ARRAY[1]}"
der
By default, the read builtin allows \ to escape characters. To turn off this behavior, use the -r option. It is not often you will find a case where you do not want to use -r.
string="I'm\nNed\nNederlander
I'm\nLucky\nDay
I'm\nDusty\nBottoms"
arr=()
while read -r line; do
arr+=("$line")
done <<< "$string"
In order to do this in one-line (like you were attempting with read -a), actually requires mapfile in bash v4 or higher:
mapfile -t arr <<< "$string"
mapfile is more elegant, but it is possible to do this in one (ugly) line with read (useful if you're using a version of bash older than 4):
IFS=$'\n' read -d '' -r -a arr <<< "$string"

Resources