Trying to read a file in bash and grep for a substring, store that substring in an array
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
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.
Err.
sn=( echo ... )isn't creating an array with the output of the pipeline, it's creating an array withechoas its first element.– Charles Duffy
11 mins ago