Làm cách nào để xác định các dòng trong tệp trong một độ dài nhất định


12

Tôi muốn tìm các dòng trong mã của tôi vượt quá một độ dài nhất định. Mã của tôi là trong nhiều tập tin. Cách tốt để làm điều này là gì?

Tôi muốn biết các tập tin và số dòng; nội dung sẽ được ưa thích, nhưng không cần thiết. Mục đích của bài tập là sau đó tìm ra cách phá vỡ các dòng (có thể là thủ công).


Bạn muốn kết quả như thế nào? Là chính các dòng (nội dung của chúng, như trong grep), hoặc như số dòng, hoặc như một cái gì đó khác (có lẽ bạn muốn áp dụng một hành động khác trên chúng)? Có lẽ cách triệu tập nhất để làm điều này phụ thuộc vào những gì sẽ được thực hiện với những dòng này tiếp theo.
imz - Ivan Zakharyaschev

@ imz - IvanZakharyaschev Điểm tốt. Câu hỏi cập nhật.
Marcin

Câu trả lời:


13

Với grep:

grep -En '.{12}' file

Đối với các dòng dài ít nhất 12 ký tự.

Với một số tệp:

find . -type f -exec grep -En '.{12}' {} +

Một số greptriển khai như GNU grep, có thể tự tìm tệp.

grep -rEn '.{12}' .

Nhưng hãy cẩn thận với các liên kết tượng trưng và các tệp không thường xuyên khác.


Tôi thích điều này bởi vì nó đơn giản, và tôi đã hy vọng làm được điều gì đó như thế này (vẫn chưa có được nó).
Marcin

12

Giải pháp AWK

awk '{       
if (length($0) > 5)
        print $0;'} yourfile

Hoặc, chính xác hơn:

awk 'length > 5' file

9
Chúng tôi có thể rút ngắn phiên bản của bạnawk 'length > 5'
cuonglm

Gnouc là một kẻ giết người niềng răng;)
Ouki

1
+1 choawk 'length > 5'

3
Với GNU awk, phần nào kém thanh lịch nhưng súc tíchawk '/^.{6,}/'
iruvar

3
@ 1_CR, Đó là POSIX và có thể rút ngắn thành awk '/.{6}/'(thực ra là GNU awk cho đến khi gần đây được sử dụng là nơi không hoạt động trừ khi bạn chuyển POSIXLY_CORRECT vào môi trường của nó).
Stéphane Chazelas

5

Vì một điều còn thiếu là một sedgiải pháp

sed -n '/^.\{6,\}/p' file

5

Giải pháp Bash

#!/bin/bash

count=0

while read; do
    ((++count)) 
    len=${#REPLY}
    if ((len > 80)); then
        echo "Line $count is $len characters."
    fi
done

Vì vậy, ví dụ , ./whatever.sh < input.file. Điều này không bao gồm dòng mới bằng cách trừ 1 từ $len; nếu điều đó không được mong muốn hoặc đầu vào của bạn sử dụng các kết thúc CRLF, bạn nên điều chỉnh cho phù hợp.


1
Tại sao không ${#line}tránh exprngã ba?
iruvar

1
ha ha, +1 cho bashgiải pháp thuần túy . Nhưng xin lưu ý rằng trừ khi bạn dán IFS=trước mặt read, các không gian hàng đầu sẽ bị bỏ qua.
iruvar

1
Thêm vào một vài bash thực hành tốt. Ngoài ra, xin lưu ý rằng dòng mới không được đưa vào $lineđể không cần phải trừ đi.
iruvar

2
@ 1_CR thực sự nếu bạn không readđặt tên để đọc, nó sẽ đọc vào REPLYvà bao gồm tất cả các khoảng trắng. Không IFScần thiết lập.
kojiro

2
Điều đó sẽ cực kỳ chậm và đặc biệt xử lý các ký tự dấu gạch chéo ngược. while readvòng lặp để xử lý văn bản là thực tế xấu.
Stéphane Chazelas

4

Với perl(ví dụ), giả sử bạn đang tìm kiếm các dòng dài hơn 80 ký tự:

Để hiển thị các dòng:

$ perl -nle 'print if length > 80' your_file

Để hiển thị số dòng:

$ perl -nle 'print "$.\n" if length > 80' your_file

Hoặc cả hai:

$ perl -nle 'print "[$.]:  $_\n" if length > 80' your_file

3
Bạn nên thêm -ldòng lệnh, perlsẽ đếm ngắt dòng trong dòng của bạn.
cuonglm

1

Ruby:

ruby -lne 'puts $_ if $_.size > 5' intputfile

Con trăn

python -c "import sys;[ sys.stdout.write(''.join(line)) for line in sys.stdin if len(line.strip()) > 5 ]" < inputfile

1

Đây là một giải pháp bash khác (bash 4):

minlen=5 # minimum length of a line
mapfile -tO1 < inputfile # Map the file to the array MAPFILE (by default)
                         # Start the array at index 1
for i in "${!MAPFILE[@]}"; do
  (( ${#MAPFILE[i]} > minlen )) || unset MAPFILE[i] # Remove shorter elements
done

Mảng kết quả là thưa thớt, vì vậy các chỉ số mảng được duy trì. Vì chúng tôi bắt đầu từ 1, các chỉ số là số dòng của các dòng chúng tôi giữ. Chúng tôi chỉ có thể xuất các số dòng đó:

printf 'Long lines found at: '
printf '%d, ' "${!MAPFILE[@]}"
echo

Hoặc chúng ta có thể tự xuất các dòng:

printf '%s\n' "${MAPFILE[@]}"
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.