Saya memiliki file di subdirektori dari direktori saat ini yang mungkin atau mungkin tidak memiliki baris baru di akhir; bagaimana saya bisa menemukan file yang tidak memiliki baris baru di akhir?
Saya sudah mencoba ini:
find . -name '*.styl' | while read file; do
awk 'END{print}' $file | grep -E '^$' > /dev/null || echo $file;
done
tetapi tidak berhasil. awk 'END{print}' $file
mencetak baris sebelum baris baru yang kosong, sama dengan tail -n 1 $file
.
awk 'END{print}' $file
: ini benar-benar mengabaikan isi $ file, dan setelah menyelesaikan parsing semua file yang terkandung dalam "$ file" itu menambahkan baris baru. Karena ini adalah satu-satunya yang dicetak perintah awk, maka dapat diganti dengan:printf '\n'
(tanpa mentino $ file sama sekali) dan melakukan hal yang sama. Saya pikir ini BUKAN apa yang Anda tuju (yaitu: cetak baris terakhir file?)c
dan begitu juga FreeBSD, tapi saya tidak melihat itu didokumentasikan sebagai tergantung implementasi: gnu.org/software/gawk/manual/… . Jadi itu memang terjadi tetapi tidak selalu.Jawaban:
Untuk memperjelas, karakter LF (alias
\n
atau baris baru) adalah pembatas garis , itu bukan pemisah garis. Garis tidak selesai kecuali diakhiri oleh karakter baris baru. File yang hanya berisia\nb
bukan file teks yang valid karena berisi karakter setelah baris terakhir. Sama untuk file yang hanya berisia
. File yang berisia\n
berisi satu baris tidak kosong.Jadi file yang diakhiri dengan setidaknya satu baris kosong berakhir dengan dua karakter baris baru atau berisi satu karakter baris baru.
Jika:
Keluaran
\n
atau\n \n
, maka file tersebut berisi setidaknya satu baris kosong yang tertinggal. Jika tidak menghasilkan apa-apa, maka itu file kosong, jika itu output<anything-but-\0> \n
, maka itu berakhir pada baris yang tidak kosong. Yang lainnya, ini bukan file teks.Sekarang, untuk menggunakannya untuk menemukan file yang berakhir pada baris kosong, OK itu efisien (terutama untuk file besar) karena hanya membaca dua byte terakhir dari file, tetapi pertama-tama output tidak mudah diurai secara terprogram terutama mengingat bahwa itu adalah tidak konsisten dari satu implementasi
od
ke yang berikutnya, dan kita perlu menjalankan satutail
dan satuod
per file.(untuk menemukan file yang berakhir pada baris kosong) akan menjalankan perintah sesedikit mungkin tetapi berarti membaca konten lengkap dari semua file.
Idealnya, Anda membutuhkan sebuah shell yang dapat membaca akhir file dengan sendirinya.
Dengan
zsh
:sumber
are_textfiles () { nontext=0; rem="return 0 if all args are files with terminating newline, or n [=number of non-textfiles]" ; for f in "$@" ; do [ -f "$f" ] && { tail -c 1 "$f" | od -An -vtc | grep "\\n" ;} >/dev/null 2>&1 || ((nontext++)) ; done ; return $nontext ; }
. Gunakan sebagai:if ( are_textfiles this that otherthing ) ; then echo all are text files ; else echo "are_textfiles returned : $?" ; fi
Dengan
gnu sed
dan shell sepertizsh
(ataubash
denganshopt -s globstar
):ini memeriksa apakah baris terakhir dari setiap file tidak kosong, jika demikian ia mencetak nama file.
Jika Anda menginginkan yang sebaliknya (cetak nama file jika baris terakhir kosong) ganti saja
/./
dengan/^$/
sumber
-s
beraksi sebelumnya. GNU terima kasih!File teks yang dihentikan dengan benar dengan baris terakhir yang kosong berakhir menjadi dua
\n
.Kemudian, kami berharap itu
tail -c2
harus sama dengan$'\n\n'
.Sayangnya ekspansi perintah menghapus garis baru. Kami perlu sedikit penyesuaian.
Kami bahkan dapat memperluas sedikit untuk memeriksa file mana yang gagal memiliki baris baru yang tertinggal:
Perhatikan bahwa baris baru dapat diubah menjadi sesuatu seperti
$'\r\n
jika diperlukan.Dalam hal itu, ubah juga
tail -c2
ketail -c4
.sumber
sumber
cat $file 2>&1 /dev/null
, atau jika ini hanya Bashcat $file &> /dev/null
,.$file
mana saja yang digunakan - dan tolong, gunakan$(commands ...)
sebagai ganti`backticks`
...