繁体   English   中英

Bash脚本:为什么此文件中缺少最后一行?

[英]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避免加回定界符,但前提是您的行不完整。

其次,我发现,当提供readNAME (你的情况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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM