Trying to read a file in bash and grep for a substring, store that substring in an array

The name of the picture


Trying to read a file in bash and grep for a substring, store that substring in an array



I have a file named test.txt that has some data as follows:


*************************** 19. row ***************************
created_at: 2018-07-02 19:57:58
deleted_at: 2018-07-03 14:17:05
serial_num: 1269043217201
*************************** 20. row ***************************
created_at: 2018-07-02 19:57:58
deleted_at: 2018-07-03 14:17:05
serial_num: 1269043217202



I need to store all the serial numbers in an array. I've tried something basic to print:


filename="test.txt"
c=0
while read -r line
do
echo $line | grep serial_num | sed -n -e 's/serial_num: //p'
done < "$filename"



This prints data like which looks good:


1280521737734
1280521737735
1280521737736



But when I add


sn=(echo $line | grep serial_num | sed -n -e 's/serial_num: //p')
echo $sn



This starts to print blank lines as well. How do I avoid that?
Also doing this


servs[$c] = $sn
c=$(expr $c + 1)



returns


./test.sh: line 138: servs[0]: command not found
./test.sh: line 138: servs[1]: command not found
./test.sh: line 138: servs[2]: command not found





Err. sn=( echo ... ) isn't creating an array with the output of the pipeline, it's creating an array with echo as its first element.
– Charles Duffy
11 mins ago


sn=( echo ... )


echo





As another aside, shell-builtin math -- part of the POSIX sh standard since 1991 -- should be used in place of expr. That is, c=$(( c + 1 )). This is far more efficient, as any command substitution ($(...)) requires forking off a subshell, and /bin/expr is an external command that then needs to be linked/loaded/etc.
– Charles Duffy
8 mins ago




expr


c=$(( c + 1 ))


$(...)


fork


/bin/expr





(Also, backticks are only for spans of less than a line; for multi-line code formatting, use four-space indents; this also enables syntax highlighting).
– Charles Duffy
2 mins ago





Also, servs[$c] = $sn doesn't work because of the spaces around the =. It would be an assignment if you made it servs[$c]=$sn.
– Charles Duffy
2 mins ago




servs[$c] = $sn


=


servs[$c]=$sn




1 Answer
1



Assuming bash 4.0 or newer:


readarray -t sn < <(awk '/serial_num:/ { print $2 }' <"$filename")
declare -p sn # print array content



With an older release:


sn=( )
while read -r line; do sn+=( "$line" ); done < <(awk '/serial_num:/ { print $2 }' <"$filename")
declare -p sn # print array content



With an older release, and in pure/native bash:


sn=( )
while IFS=$' tn' read -r key val; do
[[ $key = serial_num: ]] && sn+=( "$val" )
done
declare -p sn






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Arduino Mega cannot recieve any sketches, stk500_recv() programmer is not responding

Visual Studio Code: How to configure includePath for better IntelliSense results

Future solutions