Creating an array from a text file in Bash

前端 未结 6 1815
小鲜肉
小鲜肉 2020-11-22 10:25

A script takes a URL, parses it for the required fields, and redirects its output to be saved in a file, file.txt. The output is saved on a new line each time a fie

相关标签:
6条回答
  • 2020-11-22 11:04

    Use the mapfile command:

    mapfile -t myArray < file.txt
    

    The error is using for -- the idiomatic way to loop over lines of a file is:

    while IFS= read -r line; do echo ">>$line<<"; done < file.txt
    

    See BashFAQ/005 for more details.

    0 讨论(0)
  • 2020-11-22 11:05

    You can do this too:

    oldIFS="$IFS"
    IFS=$'\n' arr=($(<file))
    IFS="$oldIFS"
    echo "${arr[1]}" # It will print `A Dog`.
    

    Note:

    Filename expansion still occurs. For example, if there's a line with a literal * it will expand to all the files in current folder. So use it only if your file is free of this kind of scenario.

    0 讨论(0)
  • 2020-11-22 11:09

    This answer says to use

    mapfile -t myArray < file.txt
    

    I made a shim for mapfile if you want to use mapfile on bash < 4.x for whatever reason. It uses the existing mapfile command if you are on bash >= 4.x

    Currently, only options -d and -t work. But that should be enough for that command above. I've only tested on macOS. On macOS Sierra 10.12.6, the system bash is 3.2.57(1)-release. So the shim can come in handy. You can also just update your bash with homebrew, build bash yourself, etc.

    It uses this technique to set variables up one call stack.

    0 讨论(0)
  • 2020-11-22 11:11

    mapfile and readarray (which are synonymous) are available in Bash version 4 and above. If you have an older version of Bash, you can use a loop to read the file into an array:

    arr=()
    while IFS= read -r line; do
      arr+=("$line")
    done < file
    

    In case the file has an incomplete (missing newline) last line, you could use this alternative:

    arr=()
    while IFS= read -r line || [[ "$line" ]]; do
      arr+=("$line")
    done < file
    

    Related:

    • Need alternative to readarray/mapfile for script on older version of Bash
    0 讨论(0)
  • 2020-11-22 11:13

    Use mapfile or read -a

    Always check your code using shellcheck. It will often give you the correct answer. In this case SC2207 covers reading a file that either has space separated or newline separated values into an array.

    Don't do this

    array=( $(mycommand) )
    

    Files with values separated by newlines

    mapfile -t array < <(mycommand)
    

    Files with values separated by spaces

    IFS=" " read -r -a array <<< "$(mycommand)"
    

    The shellcheck page will give you the rationale why this is considered best practice.

    0 讨论(0)
  • 2020-11-22 11:25

    You can simply read each line from the file and assign it to an array.

    #!/bin/bash
    i=0
    while read line 
    do
            arr[$i]="$line"
            i=$((i+1))
    done < file.txt
    
    0 讨论(0)
提交回复
热议问题