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.

Andrew Prock
sumber

Jawaban:

270

Menggunakan wc (GNU coreutils) 7.4:

wc -L filename

memberi:

101 filename
Daniel
sumber
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

Titik biru muda
sumber
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 
Ramon
sumber
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"
Jens
sumber
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
Anonim
sumber
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

Chris Koknat
sumber
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
John Kearney
sumber
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
Wangf
sumber
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.

rsp
sumber
3

Berikut adalah referensi dari anwser

cat filename | awk '{print length, $0}'|sort -nr|head -1

http://wtanaka.com/node/7719

Nadir SOUALEM
sumber
1
Script awk kedua hanya akan memberi tahu Anda panjang terpanjang, tidak menunjukkan baris terpanjang.
rsp
1
Ayo..Ini sama dengan dua jawaban pertama yang ditambahkan dengan referensi.
Pale Blue Dot
@ rsp: saya membunuh anwser kedua
Nadir SOUALEM
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
eddiegroves
sumber
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"
Jon
sumber
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
martin clayton
sumber
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

Ivansito87
sumber