Home > Mobile >  How to split a multiple line string by newline and capture it into array in bash script?
How to split a multiple line string by newline and capture it into array in bash script?

Time:01-18

Here is my bash script statement list -

    cert_list=$(keytool -list -rfc -keystore /data/cert/mykeystore.jks -storepass  mypasswd -noprompt  | grep -i 'Entry type:\|Alias name:')
    echo "OUTPUT IS:$cert_list"
    IFS=$'\n' StringArray=(${cert_list//$'\n'/ })

   for val in ${StringArray[@]}; do
     echo "##: $val"
   done

The output is -

Alias name: root
Entry type: trustedCertEntry
Alias name: tomcat
Entry type: PrivateKeyEntry
##: Alias name: root Entry type: trustedCertEntry Alias name: tomcat Entry type: PrivateKeyEntry

I am expecting for loop output like -

##: Alias name: root
##: Entry type: trustedCertEntry
##: Alias name: tomcat
##: Entry type: PrivateKeyEntry

CodePudding user response:

The main problem is this line:

IFS=$'\n' StringArray=(${cert_list//$'\n'/ })

The ${cert_list//$'\n'/ } part takes the certificate list, and replaces all newlines in it with spaces, making it all one long line (and since it gets split on newlines, when it's stored as an array it becomes just a single long element).

A secondary problem is that the IFS=$'\n' assignment is permanent, and may cause trouble later; it's best to set IFS back to normal as soon as possible after changing it like this.

I'd recommend using readarray (aka mapfile) to do this:

readarray -t StringArray <<<"$cert_list"

Also, in the loop (for val in ${StringArray[@]}; do) the lack of quotes means that each element of the array will be word-split (and possibly expanded as a filename wildcard). This happens not to cause trouble here because IFS is messed up, but it's better to fix it properly with double-quotes:

for val in "${StringArray[@]}"; do

CodePudding user response:

  • Use mapfile to split a newline-delimited string into an array.
  • Do not forget to wrap the array variable ${StringArray[@]} with double quotes.

Then please try:

mapfile -t StringArray <<< "$cert_list"

for val in "${StringArray[@]}"; do
    echo "##: $val"
done

Output:

##: Alias name: root
##: Entry type: trustedCertEntry
##: Alias name: tomcat
##: Entry type: PrivateKeyEntry
  •  Tags:  
  • Related