子串检测无法检测换行符

问题描述

我的代码遍历了一个文本文件并对其进行了一些处理。我最终在处理(缺少)换行符时遇到了麻烦。我想测试该行在一行的末尾是否有换行符。如果确实如此,我想在文件的行中添加一个换行符。现在,我的代码根本没有添加任何新行,我不太确定原因。

已经谷歌搜索但没有任何效果

while read line || [ -n "$line" ]; do
 ...#Do things
        SUB="\n"
        if [[ "$line" =~ .*"$SUB".* ]]; then
            echo "It's there."
            printf "\n" >> $DEC
        fi
done <ip.txt

我只能使用 bash(没有 sed、awk 等)。

我想要:

案例 1:

ip:

Line1 (\n here)
Line2 (\n here)
Line3(no \n here)

输出

line1 (\n here)
line2 (\n here)
line3 (no \n here)

情况 2:

ip:

Line1 (\n here)
Line2(\n here)
Line3(\n here)

输出

line1 (\n here)
line2 (\n here)
line3 (\n here)

但我明白了:

line1(no space)line2(no space)line3

对于这两种情况

解决方法

您当前的方法有两个问题。第一个是 read 从行尾删除换行符,因此您无法检查换行符的结果 - 它不会在那里。如果 read 遇到文件结尾而不是换行符,则会返回错误状态,这就是为什么您需要 || [ -n "$line" ] 来防止循环在读取未终止行时退出。

第二个问题是SUB="\n"在变量中存储了一个反斜杠和一个“n”;要获得换行符,请使用 SUB=$'\n'

根据您在循环中尝试执行的其他操作,有多种选择。如果在文件末尾添加缺少的换行符是唯一的目标,那么 this question 的答案中有很多选项。

如果您需要通读这些行,在shell中处理它们,然后在末尾添加缺少的换行符的情况下输出它们,那么只需使用当前循环,并用换行符输出每一行——您需要添加它,无论它最初是否存在,如果你总是添加它,它就会一直存在。

如果你需要明确地找出最后一行是否有换行符,如果有的话做一些不同的事情,一个选择是稍微修改你的原始代码:

while read line; do
    # process lines that had newlines at the end
done <ip.txt
if [ -n "$line" ]; then
    # final line was missing a newline; process it here
fi

另一种选择是将整个文件读入一个数组(每一行作为一个数组条目),因为 mapfile 不会删除行终止符(除非您特别要求它使用 -t) :

mapfile ipArray <ip.txt
for line in "${foo[@]}"; do
    if [[ "$line" = *$'\n' ]]; then
        # Process line with newline at end
        cleanLine="${line%$'\n'}"    # If you need the line *without* newline
    else
        # Process line without newline
    fi
done