Linux 脚本未读取文件的最后一行
我在windows中使用记事本创建了一个文件:Linux 脚本未读取文件的最后一行,linux,shell,unix,Linux,Shell,Unix,我在windows中使用记事本创建了一个文件: 26453215432460 23543265235421 38654365876325 12354152435243 我有一个脚本,它将读取每一行,并在每一行中创建一个类似于其他文件的命令,并且不考虑空白行: CRE:EQU,264532154324600,432460,1; 现在,如果我在最后一行数字123541524352243后按enter键保存输入文件,则输出文件由上面对应于所有数字的命令
26453215432460
23543265235421
38654365876325
12354152435243
我有一个脚本,它将读取每一行,并在每一行中创建一个类似于其他文件的命令,并且不考虑空白行:
CRE:EQU,264532154324600,432460,1;
现在,如果我在最后一行数字123541524352243
后按enter键保存输入文件,则输出文件由上面对应于所有数字的命令组成(包括最后一行12354152435243
:
CRE:EQU,264532154324600,432460,1;
CRE:EQU,235432652354210,235421,1;
CRE:EQU,386543658763250,876325,1;
CRE:EQU,123541524352430,435243,1;
但是,如果我保存文件,在键入最后一个数字后(即在此12354152435243
之后)不按enter键,那么在脚本执行后,我看不到输出文件具有最后一个数字的命令:
CRE:EQU,264532154324600,432460,1;
CRE:EQU,235432652354210,235421,1;
CRE:EQU,386543658763250,876325,1;
有人能解释一下代码中的错误吗:
while read LINE
do
[ -z "$LINE" ] && continue
IMEI=`echo $LINE | sed 's/ //g' | sed -e 's/[^ -~]//g'`
END_SERIAL=`echo $IMEI | cut -c9- | sed 's/ //g' | sed -e 's/[^ -~]//g'`
echo "CRE:EQU,${IMEI}0,${END_SERIAL},${list},,${TODAY};" >> /apps/ins/list.out
done < "${FILE_NAME}"
读取行时
做
[-z“$LINE”]&继续(&C)
IMEI=`echo$LINE | sed's///g'| sed-e's//[^-~]///g'`
END|u SERIAL=`echo$IMEI | cut-c9-| sed's///g'| sed-e's//[^-~]/g'`
echo“CRE:eq,${IMEI}0,${END_SERIAL},${list},${TODAY};”>>/apps/ins/list.out
完成<“${FILE_NAME}”
如果您执行了
帮助阅读,请提供帮助,它说的是for-d delim将继续,直到读取delim的第一个字符,而不是换行符
因此,读取将继续,直到到达\n
或指定-d delim
因此,您可能需要更改delim,或者您可以尝试read-e
read
需要在行尾读取输入。请尝试
echo -n $'a\nb' | while read x ; do echo $x ; done
它只打印a
使用
grep . "${FILE_NAME}" | while read LINE
或
该文件包含4行(尽管最后一行不是“正确的”)
通常的shell例程,如read
或wc
查找行尾。因此
$ wc -l file.txt
3 file.txt
当你搜索''
(空字符串)时,grep会返回找到字符串的每一行,所以
$ grep '' file.txt
印刷品
line
another
no line ending here>
当grep打印出找到的行时-确保末尾存在多个“\n”,因此
$ grep '' file.txt | wc -l
返回
4
因此,对于这些情况,最好将grep
与-c
(count)一起使用,而不是wc
$ grep -c '' file.txt
4
现在,
点。点表示任何字符。因此,当你搜索
时,你会得到至少包含一个字符的所有行。因此,它将跳过所有不包含任何字符的行=跳过空行。因此
同样,添加的行结束于最后一行(并跳过空行)。请记住,
(空格)也是字符,因此当该行仅包含一个空格时,它不是空的。计算非空行
$ grep . file.txt | wc -l
3
或者更快
$ grep -c . file.txt
3
read将一直读取,直到找到新行,当它找到新行时,它将返回该行。但是,如果文件结束时没有新行,read会将其视为错误。因此,即使read已将返回变量设置为line read直到现在为止,read
的返回代码设置为指示错误。现在,读取时的…
只有当命令执行成功时才会执行此循环体,而这里不是这样。因此,您错过了最后一行
为了克服这一问题,您可以更改条件,同时检查返回的变量是否为空。因此,即使读取失败,条件也会成功,因为变量已设置到文件末尾
这与不同操作系统中的行结尾无关,我的意思是它在某种程度上是相关的,但确切的根本原因始终是读取
无法在行/文件的末尾找到新行,最后一行缺少循环体
下面是一个例子
[[bash_prompt$]]$ echo -ne 'hello\nthere' > log
[[bash_prompt$]]$ while read line; do echo $line; done < log
hello
[[bash_prompt$]]$ while read line || [ -n "$line" ]; do echo $line; done < log
hello
there
[[bash_prompt$]]$
[[bash\u prompt$]$echo-ne'hello\n here'>日志
读取行时[[bash_prompt$]]$;执行echo$行;完成<日志
你好
读取行时[[bash_prompt$]]$;执行echo$行;执行
我想知道这是否与Windows与*nix行结尾有关。(可能不是,但你永远不知道…)请尝试在HexFiend之类的十六进制编辑器中打开该文件,然后查看最后一个字符。是的,我正在考虑使用回车符或\n
字符。您可能可以将行结尾更改为Unix行结尾,而不是Windows行结尾。在输入文件之后,我的脚本中已经添加了dos2unix
抓取。你的意思是,这不管用吗?记事本有一个愚蠢的想法,即最后一行不需要任何类型的终止符。如果你不确保手动以换行符结束文件,它保存的内容从技术上讲不是有效的文本文件,因为文本文件是由带终止符的行组成的。read-e
对我不起作用echo-n$'a\nb'|读取时-ex;do echo$x;done
-ksh:read:-e:unknown选项
用法:read[-ACprsv][d delim][u fd][t timeout][n nchar][n nchar][var?prompt][var…]
对k-shell不起作用吗?@Siddharth:The-e
并不重要,我只是在尝试nkon的建议。非常好,这很有效。请您解释一下我为什么在$文件中使用greppin
的逻辑。非常感谢这个技巧。Cheers@Siddharth添加解释阅读-e
不适用于我echo-n$'a\nb'|而read-e x;do echo$x;done
-ksh:read:-e:未知选项用法:read[-ACprsv][d delim][u fd t timeout][n nchar][n nchar][var?prompt][var…]
同时使用delim
和-d
选项将增加我的代码以使几行安静下来,因为我必须首先复制输入文件,每个非空行都有一个字符作为delimeter,然后我必须将其馈送到read-d delim
。
$ grep . file.txt
line
another
no line ending here>
$ grep . file.txt | wc -l
3
$ grep -c . file.txt
3
[[bash_prompt$]]$ echo -ne 'hello\nthere' > log
[[bash_prompt$]]$ while read line; do echo $line; done < log
hello
[[bash_prompt$]]$ while read line || [ -n "$line" ]; do echo $line; done < log
hello
there
[[bash_prompt$]]$