簡體   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