[英]Bash scripting: why is the last line missing from this file append?
我正在编写一个bash脚本,以逐行读取一组文件并执行一些编辑。 首先,我只是尝试将文件移至备份位置并按原样将其写出,以测试脚本是否正常运行。 但是,它无法复制每个文件的最后一行。 这是代码段:
while IFS= read -r line
do
echo "Line is ***$line***"
echo "$line" >> $POM
done < $POM.backup
复制文件时,我显然想保留空格,这就是为什么将IFS设置为null的原因。 从输出中可以看到正在读取每个文件的最后一行,但是它从未出现在输出中。
我还尝试了另一种变体,它确实打印了最后一行,但在其中添加了换行符:
while IFS= read -r line || [ -n "$line" ]
do
echo "Line is ***$line***"
echo "$line" >> $POM
done < $POM.backup
什么是执行此读写操作,以正确的空格完全插入文件且未添加换行符的方式完全写入文件的最佳方法?
添加换行(LF)的命令不是 read
命令,而是echo
命令。 read
不返回与仍连接在其分隔符行; 相反,它将剥离定界符(也就是说,如果它只是在一行完整的行中出现,那么它将剥离IOW)。
因此,要解决该问题,必须使用echo -n
避免加回定界符,但前提是您的行不完整。
其次,我发现,当提供read
与NAME
(你的情况line
),它TRIMS开头和结尾的空白,我不认为你想要的。 但这可以通过完全不提供NAME
并使用默认的返回变量REPLY
,它将保留所有空白。
因此,这应该工作:
#!/bin/bash
inFile=in;
outFile=out;
rm -f "$outFile";
rc=0;
while [[ $rc -eq 0 ]]; do
read -r;
rc=$?;
if [[ $rc -eq 0 ]]; then ## complete line
echo "complete=\"$REPLY\"";
echo "$REPLY" >>"$outFile";
elif [[ -n "$REPLY" ]]; then ## incomplete line
echo "incomplete=\"$REPLY\"";
echo -n "$REPLY" >>"$outFile";
fi;
done <"$inFile";
exit 0;
编辑:哇! 查尔斯·达菲(Charles Duffy)的三个出色建议,下面是更新的脚本:
#!/bin/bash
inFile=in;
outFile=out;
while { read -r; rc=$?; [[ $rc -eq 0 || -n "$REPLY" ]]; }; do
if [[ $rc -eq 0 ]]; then ## complete line
echo "complete=\"$REPLY\"";
printf '%s\n' "$REPLY" >&3;
else ## incomplete line
echo "incomplete=\"$REPLY\"";
printf '%s' "$REPLY" >&3;
fi;
done <"$inFile" 3>"$outFile";
exit 0;
如果line不是一行,请添加新行。 像这样:
while IFS= read -r line
do
echo "Line is ***$line***";
printf '%s' "$line" >&3;
if [[ ${line: -1} != '\n' ]]
then
printf '\n' >&3;
fi
done < $POM.backup 3>$POM
经过审查,我想知道是否:
{
line=
while IFS= read -r line
do
echo "$line"
line=
done
echo -n "$line"
} <$INFILE >$OUTFILE
突出还不够...
这是我最初的建议:
#!/bin/bash
INFILE=$1
if [[ -z $INFILE ]]
then
echo "[ERROR] missing input file" >&2
exit 2
fi
OUTFILE=$INFILE.processed
# a way to know if last line is complete or not :
lastline=$(tail -n 1 "$INFILE" | wc -l)
if [[ $lastline == 0 ]]
then
echo "[WARNING] last line is incomplete -" >&2
fi
# we add a newline ANYWAY if it was complete, end of file will be seen as ... empty.
echo | cat $INFILE - | {
first=1
while IFS= read -r line
do
if [[ $first == 1 ]]
then
echo "First Line is ***$line***" >&2
first=0
else
echo "Next Line is ***$line***" >&2
echo
fi
echo -n "$line"
done
} > $OUTFILE
if diff $OUTFILE $INFILE
then
echo "[OK]"
exit 0
else
echo "[KO] processed file differs from input"
exit 1
fi
想法是始终在文件末尾添加换行符,并仅在读取的行之间打印换行符。
给定所有不包含0字节(即\\ 0字符)的文本文件,这应该适用于几乎所有文本文件,在这种情况下,将丢失0个字符字节。
可以使用初始测试来确定是否可以接受不完整的文本文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.