【问题标题】:How to read the file content into a variable in one go?如何一次性将文件内容读入变量?
【发布时间】:2012-06-11 16:58:18
【问题描述】:

在Java中,如果你确定一个文件很小,你可以使用readBytes()方法一次性读取内容,而不是逐行读取或使用缓冲区。

只是想知道 shell 脚本,我知道我们可以这样做:

    while read line
    do
      echo $line
      LINE = $line
    done < "test.file"
    echo $LINE

如果我的 test.file 是这样的:

testline1
testline2
testline3

这只给了我$LINE 的最后一行。 $LINE 包含“testline3”。

我的问题是:如何将包含多行的整个文件读入一个变量,这样我才能得到$LINE="testline1\ntestline2\ntestline3"

【问题讨论】:

  • DATA=$(cat file),但您为什么要这样做?只需在需要内容时阅读文件!
  • 与您的问题没有直接关系的两件事:首先,LINE = $line 实际上不起作用;等号周围的空间使其无效。其次,如果您正在操作要按字面意思保留的文本,则应将 IFS 设置为 null 以进行读取调用(否则每行上的前导空格将被删除)并将 -r 选项传递给 read-E 选项到echo (否则,文件中的任何反斜杠都会搞砸)。例如,请参阅下面的答案。
  • @MarkReed:我从来不明白-E 的用途,因为这是echo 的Bash 默认行为。

标签: bash shell


【解决方案1】:

处理循环内的行而不是循环之后的行。如果你真的需要变量中的文件:

var=$(<file)

【讨论】:

  • 你能解释一下这里发生了什么吗?
  • @sbhatla:该变量设置为命令替换的值,其中包含读取文件内容的重定向。它类似于var=$(cat file),但不需要生成外部可执行文件)。
【解决方案2】:

另一种选择是使用 nice mapfile 内置:

mapfile < test.file
echo "${MAPFILE[@]}"

【讨论】:

  • 没有手册页,但help mapfile 会提供更多信息。默认情况下,该实用程序会将第一行放入条目 0,将第二行放入条目 1,依此类推。您可能还想将它与 -t 选项(去除换行符)一起使用。
  • 请注意,mapfile 是在 bash 4 中引入的,因此在 OS X 上的 /bin/bash 中不可用。这可能是 bash 3 的最后一个堡垒,可能会在野外遇到,但也不是由于 Apple 和新 GPL 的许可问题,可能会更新。
  • 苹果从 Mac OS 升级到 Macos 时,包含了 bash 4.4。
【解决方案3】:

作为另一种选择,您可以构建一个行数组。如果您正在运行 bash 4+,则可以使用 mapfile 内置:

mapfile -t lines <test.file

如果您希望将行输出和存储,您可以执行以下操作:

mapfile -t lines < <(tee /dev/tty <test.file)

然后"${lines[0]}" 将是文件的第一行,"${lines[1]}" 将是第二行,依此类推。 ${#lines[@]} 将是行数; "${lines[@]}" 将是整个数组,而"${lines[*]}" 将是用空格连接在一起的行,形成一个大字符串。

对于旧版本的 bash,您可以手动构建数组:

lines=()
while IFS= read -r line
do
  printf '%s\n' "$line"
  lines+=("$line")
done < test.file

【讨论】:

  • 写成LINES+=("$line")会更容易,不是吗?
  • 是的。我在 4 年里学到了一点,似乎。很高兴知道。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-05
  • 1970-01-01
  • 2011-04-02
  • 2019-12-18
  • 2010-09-13
  • 2011-03-04
相关资源
最近更新 更多