在没有readarray或mapfile命令的情况下,将.txt文件的每一行读入Mac OS X中bash / shell / unix中的数组

时间:2016-08-07 21:50:51

标签: arrays bash macos shell unix

我正在为bash / shell中的个人库编写一个简单的目录程序。我正在使用OS X进行开发,并且我不知道如何在不访问readarraymapfile等UNIX命令的情况下配置我的程序。

以下是我要做的事情的逻辑:

  • 通过阅读一系列配置文件来初始化我的程序,这些配置文件包含在上一个会话期间编目的各种属性书。我希望每个.txt文件的信息(每行一个条目,每本书)读取并索引到一个数组中(例如titles.txt - > TITLES =(),authors.txt - > AUTHORS =(),等等...)
  • 一旦数组填充了编目信息,我想通过将新信息附加到每个相应的数组来将新书的属性输入到目录中。在确认提示之后,这个新内容将被推送到数组中,例如“你确定这些信息是否正确,如果是,它将被保存到catlog,如果没有它将被丢弃”
  • 将新书属性成功添加到相应的数组后,我想将更新后的数组更新/保存到用于初始化程序的相同.txt配置文件中,将最新信息附加到每个数组的底部档案

以下是我想对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
}

有谁知道我应该/可以使用哪些UNIX命令从shell访问这些配置文件,将其内容读入数组,然后将数组的新内容保存回.txt配置文件中?谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

您可以使用常规数组构造方法(arr[n]="asdas"arr=( "123" 45 "ss gg" ))。考虑一下这个titles.txt文件:

once upon a time
pink "cherry" troubles
obfuscator 2

只需使用bash的f=$(<filename)构造(早于mapfile,因此您应该拥有它)或其他工具(例如cat)将其读入变量。然后,您可以在while read循环中迭代它并将行保存到数组中。如果您不需要变量,您也可以只在循环中读取文件(...; done < filename)。保存回来将以类似的方式完成,只需循环遍历数组,并使用>>单独追加或重定向整个循环,您可以使用正常的空填充>

方法2 要跳过显式循环,首先将文件拆分为空格分隔的部分,然后将文件读取到数组中:

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

或者如果您还要标记标题&#39;边界更明显,你可以引用它们:

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"