POSIX sh:如何只使用shell将整个文件读入单个字符串,同时保留原始文件中的空格和换行符?

时间:2018-05-21 14:49:00

标签: string shell posix

在每个人都惊慌失措并说这个重复之前,我想指出虽然有很多关于逐行阅读文件的问题,但我发现没有一个是关于将整个文件存储到一个文件中变量。相反,大多数问题似乎是关于在读取每行时对其执行某种操作。例如,请考虑以下内容:

#!/bin/sh

while IFS='' read -r line || [ -n "$line" ]; do
    echo "$line"
done < file

我似乎无法实现这一目的。当我这样做时:

#!/bin/sh

newline='
'

string=''
while IFS='' read -r line || [ -n "$line" ]; do
    string="$string""$line""$newline"
done < file

echo "$string"

我几乎到了那里,但现在最后有一个额外的换行符,我的字符串不等于我的文件。我已经玩了很长时间了,而且我似乎无法在文件中读取我的结果字符串与我的文件完全相同。

1 个答案:

答案 0 :(得分:2)

您无条件添加换行符string="$string""$line""$newline"

只要成功读取一行(包括换行符),

read就会返回true。检查$line是否包含任何可能的最终行片段。但是当你处理它时,你需要添加换行符,因为它没有开始。只要没有最终行片段,您的脚本就可以正常工作。

通过在循环外移动[ -n "$line" ]测试可能最容易解决:

#!/bin/sh
newline='
'
string=
while IFS= read -r line; do
    string="$string$line$newline"
done < "$1"
if [ "$line" ]; then
    string="$string$line"
fi

echo "<$string>"       # markers for clarity

当然也可能是输入文件只有完整的行,额外的换行符是echo打印的行。使用printf "%s" "$string"仅打印变量的内容,无需换行或其他任何内容。有些shell有echo -n来禁止最终换行,但这是非标准的。