Baris terpanjang dalam sebuah file


198

Saya mencari cara sederhana untuk menemukan panjang baris terpanjang dalam sebuah file. Idealnya, ini akan menjadi perintah bash shell sederhana, bukan skrip.

Jawaban:


270

Menggunakan wc (GNU coreutils) 7.4:

wc -L filename

memberi:

101 filename

56
Perhatikan bahwa hanya -c -l -m -wopsi yang POSIX. -Ladalah GNUism.
Jens

4
Perhatikan juga bahwa hasil -Ltergantung pada lokal. Beberapa karakter (baik dalam byte dan dalam arti multibyte) bahkan mungkin tidak dihitung sama sekali!
Walter Tross

7
OS X:wc: illegal option -- L usage: wc [-clmw] [file ...]
Hugo

12
OS X: menggunakan homebrew, gunakan gwc untuk GNU Word Count gwc -L nama file
kaycoder

3
@xaxxon gwcada dalam coreutilsrumus, yang menginstal semua coreutils GNU dengan gawalan.
gsnedders

100
awk '{print length, $0}' Input_file |sort -nr|head -1

Untuk referensi: Menemukan baris terpanjang dalam file


12
Mengapa perintah kucing tambahan? Berikan saja nama file secara langsung sebagai argumen untuk awk.
Thomas Padron-McCarthy

18
@ Thomas. Mengekspresikannya sebagai sebuah pipa lebih umum daripada menetapkan file sebagai opsi. Dalam kasus saya, saya akan menggunakan output yang disalurkan dari permintaan basis data.
Andrew Prock

1
ini adalah jawaban terbaik karena lebih POSIX (well, berfungsi pada OS X)
MK.

5
@MK. Namun, pendekatan ini adalah O (n * log (n)) dalam jumlah baris, sedangkan pendekatan Ramon adalah O (n).
jub0bs

2
Menyortir file besar dapat memakan waktu berjam-jam untuk menyelesaikan dan mengkonsumsi gigabyte, bahkan terabyte ruang temp bergantung pada ukuran file input. Pertimbangkan menyimpan panjang terpanjang dan catatan terkait, lalu cetak dari END{}blok.
Luv2code

67
awk '{ if (length($0) > max) {max = length($0); maxline = $0} } END { print maxline }'  YOURFILE 

3
awk '{ if (length($0) > max) max = length($0) } END { print max }' YOURFILE
ke20

5
awk 'length>max{max=length}END{print max}' file
Chris Seymour

8
Jawaban ini memberikan teks dari baris terpanjang dalam file daripada panjangnya. Saya membiarkannya apa adanya meskipun pertanyaannya menanyakan panjangnya karena saya kira itu akan berguna bagi orang-orang yang datang ke halaman ini hanya dengan melihat judulnya.
Ramon

3
Mudah untuk mendapatkan hitungan menggunakan WC ..awk '{ if (length($0) > max) {max = length($0); maxline = $0} } END { print maxline }' YOURFILE | wc -c
Nick

1
Bisakah Anda memberi penjelasan bagaimana cara kerjanya?
Lnux

23

Hanya untuk bersenang-senang dan tujuan pendidikan, solusi shell POSIX murni , tanpa penggunaan kucing yang tidak berguna dan tidak ada forking untuk perintah eksternal. Mengambil nama file sebagai argumen pertama:

#!/bin/sh

MAX=0 IFS=
while read -r line; do
  if [ ${#line} -gt $MAX ]; then MAX=${#line}; fi
done < "$1"
printf "$MAX\n"

6
tidak bisa membaca dari std in (via cat) sebenarnya mengurangi utilitas ini, bukan meningkatkannya.
Andrew Prock

4
Nah, OP secara eksplisit mengatakan "file" dan tanpa < "$1"itu dapat dengan mudah membaca dari stdin. Dengan tes untuk $#itu bahkan bisa melakukan keduanya, tergantung pada jumlah args. Tidak perlu bagi kucing yang tidak berguna di dunia ini. Pemula harus diajari sesuai sejak awal.
Jens

7
Ini harus dinilai lebih tinggi, itu yang diminta pengguna. Tambahkan fungsi terpanjang () {MAX = 0 IFS = saat membaca -r line; lakukan jika [$ {# line} -gt $ MAX]; lalu MAX = $ {# line}; fi selesai echo $ MAX} ke .bashrc Anda dan Anda dapat menjalankanlongest < /usr/share/dict/words
skierpage

13
wc -L < filename

memberi

101

1
Terima kasih, saya telah mencari cara untuk mencegah wckeluaran nama file :)
Peter.O

11
perl -ne 'print length()."  line $.  $_"' myfile | sort -nr | head -n 1

Mencetak panjang, nomor baris, dan isi dari garis terpanjang

perl -ne 'print length()."  line $.  $_"' myfile | sort -n

Mencetak daftar semua garis yang diurutkan, dengan nomor dan panjang garis

.adalah operator gabungan - digunakan di sini setelah panjang ()
$.adalah nomor baris saat ini
$_adalah baris saat ini


Membutuhkan penyortiran file .. kinerja akan mengerikan bahkan untuk file berukuran sedang dan tidak akan berfungsi untuk file yang lebih besar. wc -Ladalah solusi terbaik yang saya lihat sejauh ini.
Tagar

Menggunakan 550MB 6.000.000 file teks baris sebagai sumber (British National Corpus), solusi perl mengambil 12 detik, sementara wc -Lmengambil 3 detik
Chris Koknat

wc -Lhitung saja catatan jumlah - Q ini akan menemukan garis terpanjang - tidak persis sama, jadi ini bukan perbandingan yang akurat.
Tagar

6

Poin penting yang diabaikan dalam contoh di atas.

2 contoh berikut menghitung tab yang diperluas

  wc -L  <"${SourceFile}" 
# or
  expand --tabs=8 "${SourceFile}" | awk '{ if (length($0) > max) {max = length($0)} } END { print max }'

Berikut adalah 2 tab yang tidak diperluas.

  expand --tabs=1 "${SourceFile}" | wc -L 
# or
  awk '{ if (length($0) > max) {max = length($0)} } END { print max }' "${SourceFile}"

begitu

              Expanded    nonexpanded
$'nn\tnn'       10            5

5

Terlihat semua jawabannya jangan berikan nomor baris dari baris terpanjang. Perintah berikut dapat memberikan nomor baris dan panjang kira-kira:

$ cat -n test.txt | awk '{print "longest_line_number: " $1 " length_with_line_number: " length}' | sort -k4 -nr | head -3
longest_line_number: 3 length_with_line_number: 13
longest_line_number: 4 length_with_line_number: 12
longest_line_number: 2 length_with_line_number: 11

Itu dia. Itu menemukan komentar panjang saya yang menjengkelkan. Terima kasih Bung.
Philip

Anda bisa mengambil langkah ini lebih jauh dan menghilangkan kucing. awk '{print length}' test.txt | sort -rn | head -1. Jika Anda memerlukan konten baris yang sebenarnya juga, maka awk '{print length,$0}' test.txt | sort -k1 -rn| head -1
kakoma

3

Dalam perl:

perl -ne 'print ($l = $_) if (length > length($l));' filename | tail -1

ini hanya mencetak garis, bukan panjangnya juga.



2

Hanya untuk bersenang-senang, inilah versi Powershell:

cat filename.txt | sort length | select -last 1

Dan untuk mendapatkan panjangnya:

(cat filename.txt | sort length | select -last 1).Length

4
Jadi, bahkan programmer PowerShell harus menggunakan kucing yang tidak berguna?
Jens

1
@ Jens Tidak yakin saya mengerti Anda, kucing di Powershell hanyalah alias untuk Get-Content, yang perilakunya tergantung pada konteks dan penyedia.
eddiegroves

Bisakah sortmengambil filename.txt sebagai argumen? Maka kucing tidak berguna karena sort length filename.txt | select -last 1menghindari pipa dan proses yang hanya menyalin data sekitar.
Jens

Sebagai seorang sidenote, apa yang dimaksud dengan PowerShell? Saya pikir utilitas PowerShell digunakan untuk mesin windows?
franklin

4
@ Jens, data seringkali berasal dari aliran alih-alih nama file. Ini adalah idiom alat unix standar.
Andrew Prock

2

Saya berada di lingkungan Unix, dan bekerja dengan file yang di-gzip dengan ukuran beberapa GB. Saya menguji perintah berikut menggunakan file gzip 2 GB dengan panjang catatan 2052.

  1. zcat <gzipped file> | wc -L

dan

  1. zcat <gzipped file> | awk '{print length}' | sort -u

Waktu berada di rata

  1. 117 detik

  2. 109 detik

Ini skrip saya setelah sekitar 10 kali.

START=$(date +%s) ## time of start

zcat $1 |  wc -L

END=$(date +%s) ## time of end
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"

START=$(date +%s) ## time of start

zcat $1 |  awk '{print length}' | sort -u

END=$(date +%s) ## time of end
DIFF=$(( $END - $START ))
echo "It took $DIFF seconds"

Saya tidak yakin ini adalah perbandingan yang valid, saya akan khawatir bahwa awkmanfaat versi dari caching blok disk dari wcversi yang berjalan pertama (dan biji cache disk). Anda harus mengacak urutan siapa yang dipanggil pertama kali dari sepuluh kali agar argumen ini tetap berlaku.
Canonical Chris

1

Variasi pada tema.

Yang ini akan menampilkan semua baris yang memiliki panjang garis terpanjang yang ditemukan dalam file, mempertahankan urutan mereka muncul di sumber.

FILE=myfile grep `tr -c "\n" "." < $FILE | sort | tail -1` $FILE

Jadi file saya

x
mn
xyz
123
abc

akan memberi

xyz
123
abc

0

Jika Anda menggunakan MacOS dan mendapatkan kesalahan ini: wc: illegal option -- L Anda tidak perlu menginstal GNU, lakukan ini.

Jika yang Anda ingin lakukan hanyalah mendapatkan jumlah karakter di baris terpanjang file dan Anda menggunakan OS X run:

awk '{print length}' "$file_name" | sort -rn | head -1

Sesuatu seperti ini;

echo "The longest line in the file $file_name has $(awk '{print length}' "$file_name" | sort -rn | head -1) characters"

Output:

The longest line in the file my_file has 117 characters

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.