如何使用for循环发现新行?


8

在网上的各个地方,我发现:

\015 
\012
\x0a - hex
\n
\r

全部作为各种换行符/回车符的同义词...

但是在这个小脚本中,我无法识别出遇到换行符的情况-有人可以告诉我我应该在if行中检查什么吗?

#!/bin/bash

test="this is a
test"

for a in "$test"; do

        if [[ "$a" == '\012' ]] ; then
                echo "FOUND NEWLINE"
        fi

echo "$a"

done

1
我有一个愚蠢的问题。为什么需要这样做?如果您逐行阅读输入cat | while read line; do ...; done,您将知道每次迭代都有一个回车符。如果您的输入可以是\r不带\n的文件,则只需tr '\r' '\n'在处理输入时转换文件即可。如果您只需要知道是否有多行:wc -l
nicerobot 2011年

欢迎使用Stack Exchange。请不要以这种方式编辑您的问题,因为它会使现有的答案变得毫无意义。由于您已经找到解决问题的方法,因此可以将其发布为替代答案。
吉尔(Gilles)“所以,别再邪恶了”,

@nicerobot如果根本没有换行符,wc -l则将返回0;您应该添加答案作为答案
Arcege 2011年

@lolfrog解决方案不应在问题中,您应标记具有解决方案的答案
Arcege 2011年

Answers:


6

如果直接在for循环下使用字符串,则它将按单词工作(此处仅用一个单词:$test因为引用而引起的全部内容),而不是每个字符。您需要使用带有的while循环,read以便逐个字母地解析字母,或引入将迭代字符串的数字参数。

此外,在使用时read,您需要确保不将换行符和空格解释为定界符,并强制一次read读取一个字符。

这是一个工作版本:

#!/bin/bash

test="this is a
test"

printf %s "$test" | while IFS= read -r -N 1 a; do

        if [[ "$a" == $'\n' ]] ; then
                echo "FOUND NEWLINE"
        fi

printf %s "$a"

done

您可以$'\n'$'\012'或替换$'\x0a',因为它们都代表相同的换行代码。但这不同于\015\r-表示回车(返回到行的开头)。在Linux系统上,换行用表示\n,但是在Windows上,换行用\r\n代替序列表示。这就是为什么如果您有Windows中的文本文件,也可以通过搜索来检测换行符的原因\r


简而言之,它会将带引号的转义序列\n转换为字节表示形式,因此您无需在测试语句中放置难看的带引号的换行符。
rozcietrzewiacz 2011年

4

您可以使用bash轻松地在变量中检查换行符:

[[ $var = *$'\n'* ]]

我发现使用起来更方便:

declare -r EOL=$'\n' TAB=$'\t' # at top of script
..
if [[ $var = *$EOL* ]]; then # to test (no field-splitting in [[ )

1

我建议使用tr然后test

if [ -n "$(tr -cd '\n\r' < datafile)" ]; then
    echo "NEWLINE FOUND"
fi

tr -cd除了换行符/回车符,该命令将删除所有内容。如果文件中有换行符,那么将输出-n测试将返回true的输出。


这对于不包含\rs的文件不起作用,因为命令替换会删除结尾的换行符("$(printf '\n\n\n\n\n')"为空字符串)。
斯特凡Chazelas
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.