Reputation: 21
I am working on a simple catalog program for my personal library in bash/shell. I am developing in OS X and am stuck on how I am supposed to configure my program without access to UNIX commands such as readarray
or mapfile
.
Here is the logic of what I am trying to do:
Here is what I wanted to do with mapfile
init_catalog(){
#read catalog entries into arrays
printf "%s\n" "Loading catalog..."
mapfile -t TITLES < titles.txt
mapfile -t AUTHORS < authors.txt
mapfile -t EDITORS < editors.txt
mapfile -t PUB_NAMES < pub-names.txt
mapfile -t PUB_LOCATIONS < pub-locations.txt
mapfile -t PUB_DATES < pub-dates.txt
mapfile -t PAGE_COUNTS < page-counts.txt
mapfile -t GENRES < genres.txt
mapfile -t ISBN_NUMS < isbn-nums.txt
printf "%s\n" "Catalog loaded..."
INITIALIZED="true"
}
save_catalog_entry(){
clear
printf "%s\n\n" "You have entered the following information for this work:"
printf "%s\n" "PENDING ENTRIES FOR THIS WORK..."
underline_above_text
printf "Title: $WORK_TITLE\n"
printf "Author(s): $WORK_AUTHOR\n"
printf "Editor(s): $WORK_EDITOR\n"
printf "Publisher: $WORK_PUB_NAME\n"
printf "Publication Location: $WORK_PUB_LOCATION\n"
printf "Publication Date: $WORK_PUB_DATE\n"
printf "Page Count: $WORK_PAGE_COUNT\n"
printf "Genre: $WORK_GENRE\n\n"
underline_above_text
printf "%s\n" "Is this information correct? If yes, all pending entries for this work will be saved to catalog. If no, all pending entries for this work will be discarded."
yes_or_no
if [ $USER_INPUT_YES_NO == "true" ]
then
#save input to catalog files
printf "%s\n" "${TITLES[@]}" > titles.txt
printf "%s\n" "${AUTHORS[@]}" > authors.txt
printf "%s\n" "${EDITORS[@]}" > editors.txt
printf "%s\n" "${PUB_NAMES[@]}" > pub-names.txt
printf "%s\n" "${PUB_LOCATIONS[@]}" > pub-locations.txt
printf "%s\n" "${PUB_DATES[@]}" > pub-dates.txt
printf "%s\n" "${PAGE_COUNTS[@]}" > page-counts.txt
printf "%s\n" "${GENRES[@]}" > genres.txt
printf "%s\n" "${ISBN_NUMS[@]}" > isbn-nums.txt
else
DISCARDING_ENTRIES="true"
printf "%s\n" "All input information for this work has been discarded. Please, try again."
fi
}
Does anyone know which UNIX commands I should/can use to access these config files from the shell, read their contents into arrays, and then save the new content of the arrays back into the .txt config files? Thanks for the help!
Upvotes: 2
Views: 3204
Reputation: 1433
You can use the normal array construction methods (arr[n]="asdas"
and arr=( "123" 45 "ss gg" )
). Consider this titles.txt file:
once upon a time
pink "cherry" troubles
obfuscator 2
Just read it into a variable by either using bash's f=$(<filename)
construct (older than mapfile
, so you should have it) or other tools like cat
. Then you can iterate over it in a while read
loop and save the lines to an array. If you don't need the variable, you can also just read the file in the loop (...; done < filename
). Saving back would be done in a similar manner, just looping over the array instead and either using >>
to append individually or redirecting the whole loop, where you can use a normal empty-and-fill >
.
Approach 2 To skip the explicit loop, read the file to an array by splitting it into whitespace separated pieces first:
oifs=$IFS # save a copy of the input field separator character list
IFS=$'\n' arr=( $(< titles.txt) )
IFS=$oifs # restore
$ echo "${arr[@]}"
once upon a time pink "cherry" troubles obfuscator 2
$ echo "${arr[1]}"
pink "cherry" troubles
Or if you want to also mark the titles' boundaries more obviously, you can quote them:
oifs=$IFS
IFS=$'\n' arr=( $(sed -n 's,",\\",g; s,^.*$,"&",p' titles.txt) )
IFS=$oifs
$ echo "${arr[@]}"
"once upon a time" "pink \"cherry\" troubles" "obfuscator 2"
$ echo "${arr[1]}"
"pink \"cherry\" troubles"
Upvotes: 1