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

String POSIX sh:如何仅使用shell将整个文件读入单个字符串,同时在原始文件中保留空格和换行符?,string,shell,posix,String,Shell,Posix,在大家发疯并说这是重复之前,我想指出,虽然关于逐行读取文件有很多问题,但我发现没有一个是关于将整个文件存储到单个变量中的问题。相反,大多数问题似乎是关于在读入每一行时对每一行执行某种操作。作为一个例子,考虑如下: #!/bin/sh while IFS='' read -r line || [ -n "$line" ]; do echo "$line" done < file #!/bin/sh newline=' ' string='' while IFS='' read

在大家发疯并说这是重复之前,我想指出,虽然关于逐行读取文件有很多问题,但我发现没有一个是关于将整个文件存储到单个变量中的问题。相反,大多数问题似乎是关于在读入每一行时对每一行执行某种操作。作为一个例子,考虑如下:

#!/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"
#/垃圾箱/垃圾箱
而IFS=''读-r行| |[-n“$line”];做
回音“$line”
完成<文件
我似乎无法实现我的特定目的。当我执行以下操作时:

#!/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"
#/垃圾箱/垃圾箱
新线新闻
'
字符串=“”
而IFS=''读-r行| |[-n“$line”];做
string=“$string”“$line”“$newline”
完成<文件
回显“$string”

我差不多到了,但现在末尾有一个额外的换行符,我的字符串不等于我的文件。我已经玩了很长一段时间了,我似乎无法读取文件中的内容,因此生成的字符串与我的文件完全相同。

您正在使用
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
#/垃圾箱/垃圾箱
新线新闻
'
串=
而IFS=读取-r行;做
string=“$string$line$newline”
完成<“$1”
如果[“$line”];然后
string=“$string$line”
fi
回声“#标记以清晰显示

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

您使用
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
#/垃圾箱/垃圾箱
新线新闻
'
串=
而IFS=读取-r行;做
string=“$string$line$newline”
完成<“$1”
如果[“$line”];然后
string=“$string$line”
fi
回声“#标记以清晰显示

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

不是
echo“$string”
,也许您希望
printf“%s'”$string”
,以避免
echo
添加的额外换行。样式点:
string=“$string$line$newline”
string=“${string}${line}${newline}”
似乎比使用额外的
要干净得多。与其使用
echo“$string”
,不如使用
printf'%s'$string”
,以避免使用
echo
添加的额外换行符。样式要点:
string=“$string$line$newline”
string=“${string}${line}${newline}“
似乎比使用额外的
更干净”