如何列出不以换行符结尾的文件?

如何列出正常文本( .txt )文件名,不以换行符结束?

例如:list(输出)这个文件名:

 $ cat a.txt asdfasdlsad4randomcharsf asdfasdfaasdf43randomcharssdf $ 

不要列出(输出)这个文件名:

 $ cat b.txt asdfasdlsad4randomcharsf asdfasdfaasdf43randomcharssdf $ 

Solutions Collecting From Web of "如何列出不以换行符结尾的文件?"

使用pcregrep,一个Perl兼容正则表达式版本的grep,它支持使用-M标志的多行模式,如果最后一行有换行符,可以用来匹配(或不匹配):

 pcregrep -LMr '\n$' . 

在上面的例子中,我们说在当前目录( . )中递归搜索( -r )列出不匹配的文件( -L )我们的多行( -M )正则表达式在文件末尾寻找换行符'\n$'

-L更改为-l将列出在其中具有换行符的文件。

好的轮到我了,我试试看:

 find -type f -print0 | xargs -0 -L1 bash -c 'test "$(tail -c 1 "$0")" && echo "No new line at end of $0"' 

试试这个:

 find -type f -exec sh -c '[ -z "$(sed -n "\$p" "$1")" ]' _ {} \; -print 

它将打印以空行结束的文件的文件名。 要打印不以空行结束的文件,请将-z更改为-n

如果您使用“ack”( http://beyondgrep.com )作为grep的替代方法,则只需运行以下命令:

 ack -v '\n$' 

它实际上搜索所有不匹配的行(-v)在行尾的换行符。

这应该做的伎俩:

 #!/bin/bash for file in `find $1 -type f -name "*.txt"`; do nlines=`tail -n 1 $file | grep '^$' | wc -l` if [ $nlines -eq 1 ] then echo $file fi done; 

这样调用: ./script dir

例如./script /home/user/Documents/ – >列出以\n结尾的/home/user/Documents中的所有文本文件。

这是kludgy; 有人肯定会做得更好:

 for f in `find . -name '*.txt' -type f`; do if test `tail -c 1 "$f" | od -c | head -n 1 | tail -c 3` != \\n; then echo $f; fi done 

注意,这个标题中的问题与正文中的问题是不同的(正在寻找以\ n \ n结尾的文件)。

另外一个选择:

 $ find . -name "*.txt" -print0 | xargs -0I {} bash -c '[ -z "$(tail -n 1 {})" ] && echo {}' 

这个例子在OSX上适用于我(上面的许多解决方案没有)

 for file in `find . -name "*.java"` do result=`od -An -tc -j $(( $(ls -l $file | awk '{print $5}') - 1 )) $file` last_char=`echo $result | sed 's/ *//'` if [ "$last_char" != "\n" ] then #echo "Last char is .$last_char." echo $file fi done 

这个网页上的大多数解决方案都不适合我(FreeBSD 10.3 amd64)。 Ian Will的OSX解决方案几乎总是能够工作,但是很难遵循: – (

有一个简单的解决方案,几乎总是有效:(如果$ f是文件):

sed -i''-e'$ a \'“$ f”

sed解决方案存在一个主要问题:它从来没有给你机会去检查(而不是追加换行符)。

上述解决方案都不能用于DOS文件。 我认为最便携/可脚本化的解决方案可能是我自己开发的最简单的解决方案: – )

这里是结合file / unix2dos / tail的基本sh脚本。 在生产中,您可能需要在引号中使用“$ f”并获取尾部输出(嵌入到名为last的shell变量中)为\“$ f \”

 if file $f | grep 'ASCII text' > /dev/null; then if file $f | grep 'CRLF' > /dev/null; then type unix2dos > /dev/null || exit 1 dos2unix $f last="`tail -c1 $f`" [ -n "$last" ] && echo >> $f unix2dos $f else last="`tail -c1 $f`" [ -n "$last" ] && echo >> $f fi fi 

希望这有助于某人。

由于你的问题有perl标签,我会发布一个使用它的答案:

 find . -type f -name '*.txt' -exec perl check.pl {} + 

其中check.pl是以下内容:

 #!/bin/perl use strict; use warnings; foreach (@ARGV) { open(FILE, $_); seek(FILE, -2, 2); my $c; read(FILE,$c,1); if ( $c ne "\n" ) { print "$_\n"; } close(FILE); } 

这perl脚本只是打开,每次一个,作为参数传递的文件,只读倒数第二个字符; 如果它不是一个换行符,它只是打印出文件名,否则它什么也不做。