Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux上的文件缺少EOL字符_Linux_Bash_Shell_Sed - Fatal编程技术网

Linux上的文件缺少EOL字符

Linux上的文件缺少EOL字符,linux,bash,shell,sed,Linux,Bash,Shell,Sed,我有一个文件在最后一行末尾没有EOL。当我从中读取的bash脚本没有处理最后一行时,我注意到了这一点 我是这样读的: while read LINE do ... done <thefile 读取行时 做 ... 完成这将在文件末尾添加新行: echo >> thefile 只有在EOF没有换行符时,才会在EOF处添加换行符(跳转后的解释) 如果要处理EOF中可能没有换行符的文件,必须检查循环后是否存在read输出变量: while read LINE do

我有一个文件在最后一行末尾没有EOL。当我从中读取的bash脚本没有处理最后一行时,我注意到了这一点

我是这样读的:

while read LINE
do
    ...
done <thefile
读取行时
做
...

完成这将在文件末尾添加新行:

echo >> thefile
只有在EOF没有换行符时,才会在EOF处添加换行符(跳转后的解释)

如果要处理EOF中可能没有换行符的文件,必须检查循环后是否存在
read
输出变量:

while read LINE
do
    ...
done <thefile

if [ "${LINE+defined}" = defined ]
then
    ...
fi
读取行时
做
...

done几个实用程序在输出的末尾添加换行符。例如,您可以使用剪切和执行:

cut -b 1- < thefile | 
while read LINE; do ...; done

请注意,将while放在管道中会将其放在子流程中,这可能会对脚本产生影响(例如,在循环中所做的分配不会持久),因此您可能需要使用临时文件或命名管道来修改数据。

如果文件末尾没有新行(并且不是空的),可以在文件末尾添加新行:

或者,这里有一种简单的方法可以修改循环以处理最终换行后的任何内容:

while read LINE || [ -n "$LINE" ]
do
...
在bash中,
[-n“$l”]
可以替换为
[[$l]]
<代码>[[$l]]
相当于
[[[-n$l]]
<代码>$l
不必被引用,因为在
[[
内部不执行分词和路径名扩展

$ printf 'x\ny' | while IFS= read -r l; do echo "$l"; done
x
$ printf 'x\ny' | while IFS= read -r l || [[ $l ]]; do echo "$l"; done
x
y
$(tail-c1)
仅当文件以换行符结尾或为空时才为空。
$()
从结尾删除换行符,并且
tail-c1
对于空文件为空。
-s
测试文件是否存在且不为空

f=/tmp/some\ file
[[ -s $f && $(tail -c1 "$f") ]] && printf \\n >> "$f"
sed-np
(无打印,打印)是
sed'$a\'
的替代品。BSD sed需要
-i'
,而不仅仅是
-i

sed -i '' -n p *.txt

有点不清楚您的问题是什么。有趣的是,POSIX文本文件在每一行的末尾都有一个EOL字符。谢谢。sed命令正是我想要的。尽管echo>>myfile可以工作,但不管最后一行是否已经有一个EOL,它都会附加一个EOL。
f=/tmp/some\ file
[[ -s $f && $(tail -c1 "$f") ]] && printf \\n >> "$f"
sed -i '' -n p *.txt