Có thể tìm thấy bất kỳ dòng nào trong một tập tin vượt quá 79 ký tự không?
Có thể tìm thấy bất kỳ dòng nào trong một tập tin vượt quá 79 ký tự không?
Câu trả lời:
Theo thứ tự giảm tốc độ (trên hệ thống GNU trong ngôn ngữ UTF-8 và trên đầu vào ASCII) theo các thử nghiệm của tôi:
grep '.\{80\}' file
perl -nle 'print if length$_>79' file
awk 'length>79' file
sed -n '/.\{80\}/p' file
Ngoại trừ perl
¹ một (hoặc cho awk
/ grep
/ sed
triển khai (như mawk
hoặc busybox) không hỗ trợ các ký tự nhiều byte), tính chiều dài tính theo số lượng ký tự (theo LC_CTYPE
cài đặt của miền địa phương) thay vì byte .
Nếu có các byte trong đầu vào không tạo thành một phần của các ký tự hợp lệ (đôi khi xảy ra khi bộ ký tự của miền địa phương là UTF-8 và đầu vào ở dạng mã hóa khác nhau), thì tùy thuộc vào cách triển khai giải pháp và công cụ, các byte đó sẽ được tính là 1 ký tự hoặc 0 hoặc không khớp .
.
Chẳng hạn, một dòng bao gồm 30 a
sa 0x80 byte, 30 b
giây, 0x81 byte và 30 UTF-8 é
s (được mã hóa thành 0xc3 0xa9), trong ngôn ngữ UTF-8 sẽ không khớp .\{80\}
với GNU grep
/ sed
(vì đó là 0x80 byte độc lập không khớp .
), sẽ có độ dài 30 + 1 + 30 + 1 + 2 * 30 = 122 với perl
hoặc mawk
, 3 * 30 = 90 với gawk
.
Nếu bạn muốn tính theo byte, hãy sửa miền địa phương C
với LC_ALL=C grep/awk/sed...
.
Điều đó sẽ có tất cả 4 giải pháp xem xét dòng trên chứa 122 ký tự. Ngoại trừ perl
các công cụ GNU và, bạn vẫn có các vấn đề tiềm ẩn đối với các dòng có chứa các ký tự NUL (0x0 byte).
Behavior perl
hành vi có thể bị ảnh hưởng bởi PERL_UNICODE
biến môi trường
awk
có thể đến gần hơn nếu bạn thả ($0)
, dù sao thì nó cũng tiềm ẩn;).
^
, nó sẽ nhanh hơn một chút: vd grep '^.\{80\}' file
.
grep '^.\{1000\}' file
trả về grep: invalid repetition count(s)
, trong khi awk 'length>1000' file
thành công.)
Cách tiếp cận Shell:
while IFS= read -r line || [ -n "$line" ];
do
[ "${#line}" -gt 79 ] && printf "%s\n" "$line"
done < input.txt
Cách tiếp cận Python:
python -c 'import sys;f=open(sys.argv[1]);print "\n".join([ l.strip() for l in f if len(l) >79 ]);f.close()' input.txt
Hoặc như một đoạn script ngắn để dễ đọc:
#!/usr/bin/env python
import sys
with open(sys.argv[1]) as f:
for line in f:
if len(line) > 79:
print line.strip()
Nếu chúng ta muốn loại trừ ký tự xuống dòng \n
từ tính toán, chúng ta có thể làm if len(line) > 79
đượcif len(line.strip()) > 79
Lưu ý bên lề: đây là cú pháp Python 2.7. Sử dụng print()
cho Python 3