Dòng dài nhất trong một tập tin


198

Tôi đang tìm kiếm một cách đơn giản để tìm độ dài của dòng dài nhất trong một tệp. Lý tưởng nhất, nó sẽ là một lệnh bash shell đơn giản thay vì một tập lệnh.

Câu trả lời:


270

Sử dụng wc (GNU coreutils) 7.4:

wc -L filename

cho:

101 filename

56
Lưu ý rằng chỉ có các -c -l -m -wtùy chọn là POSIX. -Llà một chủ nghĩa GNU.
Jens

4
Cũng lưu ý rằng kết quả của -Lphụ thuộc vào miền địa phương. Một số ký tự (cả theo byte và theo nghĩa đa nhân) thậm chí có thể không được tính!
Walter Tross

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

12
OS X: sử dụng homebrew, sử dụng gwc cho GNU Word Count gwc -L tên tệp
kaycoder

3
@xaxxon gwccó trong coreutilscông thức, cài đặt tất cả các lõi GNU với gtiền tố.
gsnedder

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

Để tham khảo: Tìm dòng dài nhất trong một tệp


12
Tại sao lệnh mèo thêm? Chỉ cần cung cấp tên tệp trực tiếp làm đối số cho awk.
Thomas Padron-McCarthy

18
@Thomas. Thể hiện nó như một đường ống chung chung hơn là chỉ định một tệp là một tùy chọn. Trong trường hợp của tôi, tôi sẽ sử dụng đầu ra được lấy từ một truy vấn cơ sở dữ liệu.
Andrew Prock

1
Đây là câu trả lời tốt nhất vì nó có nhiều POSIX hơn (hoạt động tốt trên OS X)
MK.

5
@MK. Tuy nhiên, cách tiếp cận này là O (n * log (n)) về số lượng dòng, trong khi cách tiếp cận của Ramon là O (n).
jub0bs

2
Sắp xếp một tệp lớn có thể mất hàng giờ để hoàn thành và tiêu thụ gigabyte, thậm chí terabyte không gian tạm thời tùy thuộc vào kích thước tệp đầu vào. Cân nhắc lưu trữ độ dài dài nhất và bản ghi liên quan của nó, sau đó in nó từ một END{}khối.
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
Câu trả lời này đưa ra văn bản của dòng dài nhất trong tệp chứ không phải độ dài của nó. Tôi đang để nó như là - mặc dù câu hỏi yêu cầu độ dài bởi vì tôi nghi ngờ nó sẽ hữu ích cho những người đến trang này chỉ nhìn vào tiêu đề.
Ramon

3
Dễ dàng đếm số bằng cách sử dụng WC ..awk '{ if (length($0) > max) {max = length($0); maxline = $0} } END { print maxline }' YOURFILE | wc -c
Nick

1
Bạn có thể giải thích rằng làm thế nào điều này hoạt động?
Lnux

23

Chỉ nhằm mục đích vui chơi và giáo dục, giải pháp vỏ POSIX thuần túy , không sử dụng con mèo vô dụng và không từ bỏ các lệnh bên ngoài. Lấy tên tệp làm đối số đầu tiên:

#!/bin/sh

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

6
không thể đọc từ std in (thông qua mèo) thực sự làm giảm tiện ích của việc này, không tăng cường nó.
Andrew Prock

4
Vâng, OP đã nói rõ ràng "tập tin" và không có < "$1"nó có thể dễ dàng đọc từ stdin. Với một bài kiểm tra cho $#nó thậm chí có thể làm cả hai, tùy thuộc vào số lượng đối số. Không cần cho những con mèo vô dụng trong thế giới này. Người mới nên được dạy cho phù hợp ngay từ đầu.
Jens

7
Điều này nên được đánh giá cao hơn, đó là những gì người dùng yêu cầu. Thêm hàm dài nhất () {MAX = 0 IFS = trong khi đọc dòng -r; làm nếu [$ {# line} -gt $ MAX]; sau đó MAX = $ {# dòng}; fi đã thực hiện echo $ MAX} cho .bashrc của bạn và bạn có thể chạylongest < /usr/share/dict/words
skierpage

13
wc -L < filename

cho

101

1
Cảm ơn, tôi đã tìm cách để ngăn chặn việc wcxuất tên tệp :)
Peter.O

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

In độ dài, số dòng và nội dung của dòng dài nhất

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

In một danh sách được sắp xếp của tất cả các dòng, với số dòng và độ dài

.là toán tử ghép - nó được sử dụng ở đây sau length ()
$.là số dòng hiện tại
$_là dòng hiện tại


Yêu cầu sắp xếp một tệp .. hiệu suất sẽ rất tệ ngay cả đối với các tệp có kích thước vừa phải và sẽ không hoạt động đối với các tệp lớn hơn. wc -Llà giải pháp tốt nhất tôi thấy cho đến nay.
Tagar

Sử dụng tệp văn bản dòng 550.000.000 6.000.000 làm nguồn (British National Corpus), giải pháp perl mất 12 giây, trong khi wc -Lmất 3 giây
Chris Koknat

wc -Lchỉ cần đếm các bản ghi số - Q này sắp tìm dòng dài nhất - không hoàn toàn giống nhau, vì vậy đây không phải là so sánh chính xác.
Tagar

6

Điểm bỏ qua quan trọng trong các ví dụ trên.

2 ví dụ sau đây đếm các tab mở rộng

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

2 tab sau đây không đếm được.

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

vì thế

              Expanded    nonexpanded
$'nn\tnn'       10            5

5

Có vẻ như tất cả các câu trả lời không đưa ra số dòng của dòng dài nhất. Lệnh sau có thể cho số dòng và độ dài khoảng:

$ 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

Chúng tôi đi đây. Điều đó tìm thấy những bình luận dài đáng ghét của tôi. Cảm ơn anh bạn.
Philip

Bạn có thể tiến thêm một bước này và loại bỏ con mèo. awk '{print length}' test.txt | sort -rn | head -1. Nếu bạn cũng cần nội dung của dòng thực tế, thì awk '{print length,$0}' test.txt | sort -k1 -rn| head -1
kakoma

3

Trong perl:

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

Điều này chỉ in dòng, không phải chiều dài của nó quá.


3

Dưới đây là tài liệu tham khảo của anwser

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

http://wtanaka.com/node/7719


1
Kịch bản awk thứ hai đó sẽ chỉ cho bạn biết độ dài dài nhất, không hiển thị dòng dài nhất.
rsp

1
Thôi nào..Những điều này giống như hai câu trả lời đầu tiên được thêm vào cùng với các tài liệu tham khảo.
Pale Blue Dot

@rsp: tôi giết anwser thứ hai
Nadir SOUALEM

2

Để giải trí, đây là phiên bản Powershell:

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

Và để có được chiều dài:

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

4
Vì vậy, ngay cả các lập trình viên powershell cũng phải sử dụng những con mèo vô dụng?
Jens

1
@Jens Không chắc tôi hiểu bạn, con mèo trong Powershell chỉ là bí danh cho Get-Content, hành vi của chúng phụ thuộc vào bối cảnh và nhà cung cấp.
eddiegroves

Có thể sortlấy filename.txt làm đối số? Sau đó, con mèo là vô dụng vì sort length filename.txt | select -last 1tránh một đường ống và một quá trình chỉ sao chép dữ liệu xung quanh.
Jens

Là một sidenote chính xác những gì là powershell? Tôi nghĩ tiện ích powershell được sử dụng cho các máy windows?
franklin

4
@Jens, dữ liệu thường xuyên đến từ một luồng thay vì tên tệp. Đây là một thành ngữ unix công cụ tiêu chuẩn.
Andrew Prock

2

Tôi đang ở trong môi trường Unix và làm việc với các tệp được nén với kích thước vài GB. Tôi đã kiểm tra các lệnh sau bằng cách sử dụng tệp được nén 2 GB với độ dài bản ghi là 2052.

  1. zcat <gzipped file> | wc -L

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

Thời gian đã ở trên tuyết

  1. 117 giây

  2. 109 giây

Đây là kịch bản của tôi sau khoảng 10 lần chạy.

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"

Tôi không chắc đây là một so sánh hợp lệ, tôi sẽ lo lắng rằng awkphiên bản được hưởng lợi từ bộ nhớ đệm khối đĩa của wcphiên bản đang chạy đầu tiên (và gieo hạt vào bộ đệm đĩa). Bạn sẽ phải chọn ngẫu nhiên thứ tự của người được gọi đầu tiên trong mười lần chạy để làm cho đối số này được duy trì.
Canonical Chris

1

Biến thể về chủ đề.

Cái này sẽ hiển thị tất cả các dòng có độ dài của dòng dài nhất được tìm thấy trong tệp, giữ nguyên thứ tự chúng xuất hiện trong nguồn.

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

Vì vậy, tôi

x
mn
xyz
123
abc

sẽ cho

xyz
123
abc

0

Nếu bạn đang sử dụng MacOS và đang gặp lỗi này: wc: illegal option -- Lbạn không cần phải cài đặt GNU sipmly làm điều này.

Nếu tất cả những gì bạn muốn làm chỉ là lấy số lượng ký tự trong dòng dài nhất của tệp và bạn đang sử dụng OS X chạy:

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

Một cái gì đó như thế này;

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

Đầu ra:

The longest line in the file my_file has 117 characters

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.