2012-01-09 38 views
43

Tôi muốn in số ký tự trong mỗi dòng của tệp văn bản bằng lệnh unix. Tôi biết nó rất đơn giản với powershellCách in số ký tự trong mỗi dòng của tệp văn bản

gc abc.txt | % {$_.length} 

nhưng tôi cần lệnh unix.

+0

Quy tắc đầu tiên về phát triển phần mềm: "không" có nghĩa là "không". Sử dụng "num" hoặc "number". –

+3

[cần dẫn nguồn]. – uprego

Trả lời

87

Sử dụng Awk.

awk '{ print length($0); }' abc.txt 
+5

Tôi nghĩ rằng 'chiều dài in; 'là tương đương và POSIX cũng như http://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html –

+1

Điều này cũng hoạt động trên os mac. – bdemarest

11
while read -r line; do echo ${#line}; done < abc.txt 

Đó là POSIX, vì vậy nó nên làm việc ở khắp mọi nơi.

Chỉnh sửa: Đã thêm -r theo đề xuất của William.

+0

+1, nhưng ... điều này sẽ thất bại nếu đầu vào chứa '\'. Sử dụng read -r –

0

Hãy thử điều này:

while read line  
do  
    echo -e |wc -m  
done <abc.txt  
+0

Bạn có nghĩa là 'echo -e | wc -m', phải không? Việc sử dụng lệnh vô dụng; shell có thể đếm các ký tự trong một biến. Cộng với 'echo -e' là hoàn toàn không tương thích và hoạt động trong một nửa các shell trong khi bắt đầu với một số trình tự thoát hoạt động trong một số khác và không có gì trong phần còn lại. –

+0

Đúng, đúng ... sai. Cảm ơn bạn đã trỏ nó. – Rahul

2

Dưới đây là ví dụ sử dụng xargs:

$ xargs -I% sh -c 'echo % | wc -c' < file 
+0

"echo%" này không xử lý các ký tự không an toàn cần trích dẫn từ trình bao. Ngoài ra "xargs" sẽ chia nhỏ tệp của bạn theo dấu cách và dòng mới, không chỉ các dòng mới như áp phích gốc được yêu cầu. – bovine

1

Tôi đã thử các câu trả lời khác được liệt kê ở trên, nhưng họ rất xa các giải pháp phong nha khi giao dịch với các tập tin lớn - đặc biệt khi kích thước của một đường đơn chiếm hơn ~ 1/4 RAM có sẵn.

Cả hai bash và awk đều slurp toàn bộ dòng, mặc dù cho vấn đề này nó không cần thiết. Bash sẽ lỗi khi một dòng quá dài, ngay cả khi bạn có đủ bộ nhớ.

Tôi đã triển khai một tập lệnh python cực kỳ đơn giản, không được tối ưu hóa khi được thử nghiệm với các tệp lớn (~ 4 GB trên mỗi dòng) không slurp và là giải pháp tốt hơn so với các tệp được cung cấp. Nếu đây là mã thời gian quan trọng để sản xuất, bạn có thể viết lại các ý tưởng trong C hoặc thực hiện tối ưu hóa tốt hơn trên cuộc gọi đọc (thay vì chỉ đọc một byte tại một thời điểm), sau khi kiểm tra xem đây có phải là nút cổ chai hay không.

Mã giả định dòng mới là ký tự linefeed, là một giả định tốt cho Unix, nhưng YMMV trên Mac OS/Windows. Hãy chắc chắn rằng tệp kết thúc bằng một dòng cấp để đảm bảo số ký tự dòng cuối cùng không bị bỏ qua.

from sys import stdin, exit 

counter = 0 
while True: 
    byte = stdin.buffer.read(1) 
    counter += 1 
    if not byte: 
     exit() 
    if byte == b'\x0a': 
     print(counter-1) 
     counter = 0 
Các vấn đề liên quan