Luke Luke - 6 months ago 48
Bash Question

Iterate an array in a shell script to save its values in a .plist and a .db

This shell script allows to programmatically save text replacements for macOS, on both


date=$(date +%s)
while read -r replace with; do
sql+="INSERT INTO 'ZUSERDICTIONARYENTRY' VALUES($((++i)),1,1,0,0,0,0,$date,NULL,NULL,NULL,NULL,NULL,\"$with\",\"$replace\",NULL);"
done < <(sed 's/\\/\\\\/g;s/"/\\"/g' ~/replacements.txt)
sqlite3 ~/Library/Dictionaries/CoreDataUbiquitySupport/$USER~*/UserDictionary/local/store/UserDictionary.db "delete from ZUSERDICTIONARYENTRY;$sql"
defaults write -g NSUserDictionaryReplacementItems "(${plist%?})"

How can I customize it so that it can read a previously declared array, instead of a
external file?


Assuming (and these are large and unfounded assumptions, necessary due to the vagueness of the question) that your array contains one entry per line of the input file:


sed 's/\\/\\\\/g;s/"/\\"/g' ~/replacements.txt


printf '%s\n' "${replacements[@]}" | sed 's/\\/\\\\/g;s/"/\\"/g'

To be clear, this is assuming a numerically-indexed array. For instance, you could generate such an array from your replacements.txt with:

# in bash 4.0 or newer
mapfile -t replacements <~/replacements.txt


# in bash 3.x or newer
replacements=( )
while IFS= read -r line; do replacements+=( "$line" ); done <~/replacements.txt