如何列出不以換行符結尾的普通文本(.txt
)文件名?如何列出不以換行符結尾的文件?
例如爲:列表(輸出)這個文件名:
$ cat a.txt
asdfasdlsad4randomcharsf
asdfasdfaasdf43randomcharssdf
$
,並沒有列出(輸出)這個文件名:
$ cat b.txt
asdfasdlsad4randomcharsf
asdfasdfaasdf43randomcharssdf
$
如何列出不以換行符結尾的普通文本(.txt
)文件名?如何列出不以換行符結尾的文件?
例如爲:列表(輸出)這個文件名:
$ cat a.txt
asdfasdlsad4randomcharsf
asdfasdfaasdf43randomcharssdf
$
,並沒有列出(輸出)這個文件名:
$ cat b.txt
asdfasdlsad4randomcharsf
asdfasdfaasdf43randomcharssdf
$
這是缺憾;肯定有人可以做得更好:
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.B.這回答了標題中的問題,它與正文中的問題不同(正在查找以\ n \ n結尾的文件)。
這應該做的伎倆:
#!/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/
- >列出/home/user/Documents
以\n
結尾的所有文本文件。
第一個改進是在之前放置'IFS = $'\ n'`。它允許用空格處理文件。第二個改進是用`$ nlines -eq 0`替換`$ nlines -eq 1`,因爲作者需要「文件名,**不會以換行符結束**」。 – 2015-04-17 12:52:58
試試這個:
find -type f -exec sh -c '[ -z "$(sed -n "\$p" "$1")" ]' _ {} \; -print
將打印爲空白行結尾的文件的文件名。要打印未以空行結尾的文件,請將-z
更改爲-n
。
如果存在包含空格的文件名,那麼使用`for ... find ... do`的答案將會失敗。 – 2011-01-07 23:33:45
你對'for .. find..`正確。http://mywiki.wooledge.org/BashPitfalls#for_i_in_.24.28ls_.2A.mp3.29 – jfs 2011-01-07 23:46:01
另一種選擇:
$ find . -name "*.txt" -print0 | xargs -0I {} bash -c '[ -z "$(tail -n 1 {})" ] && echo {}'
由於您的問題有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腳本只是打開一個,每次一個,作爲參數傳遞的文件和只讀倒數第二個字符;如果它不是換行符,它只是打印出文件名,否則它什麼也不做。
使用pcregrep,grep的的Perl兼容的正則表達式版本使用,如果最後一行有一個換行符,可以用來匹配(或不匹配)-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"'
這個例子對我的作品在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)。伊恩·威爾的 OSX解決方案確實幾乎總是工作,但相當難走: - (
有一個簡單的解決方案,它幾乎總是工作過:(如果$ f是文件):sed的
-i'-e「$ A \」「$ F」
有一個與sed的解決方案的一個主要問題:它永遠不會讓你有機會 只檢查(而不是追加一個換行符)
上述兩種解決方案對於DOS文件都是失敗的,我認爲最可行的解決方案就是prob 我自己開發的: - )
這裏是基本的sh腳本,它結合了file/unix2dos/tail。在 生產,你可能需要在引號中,用「$ F」和取尾輸出 (嵌入名爲最後的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
希望這可以幫助別人。
你只是在尋找一個文件夾的文件的寬屏幕顯示下來?你的問題不是很清楚上面的例子.. – James 2011-01-07 23:05:56
「正常txt」是什麼意思?你是在談論以*空行*(\ n \ n)結尾的文件還是隻以換行符結尾的文件?您可以使用`od -c filename`來打印文件的明確表示。 – jfs 2011-01-07 23:42:30
只是爲了強調:換行符*不與*空白*行相同。換行符是一個單獨的字符 - 它劃定了我們所看到的「行」。空白行只是一個沒有字符的「行」,通常是2個連續的換行符,沒有任何中間字符,或者是以換行符開始的文件中的第一行。有些人呼叫僅包含空格「空白」行的行,併爲2個連續換行字符保留「空行」一詞。你應該清楚你想要什麼。 – jw013 2013-07-18 21:00:22