2012-01-09 12 views

Odpowiedz

87

Użyj Awk.

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

Myślę, że 'print length;' jest odpowiednikiem, a POSIX również http://pubs.opengroup.org/onlinepubs/9699919799/utilities/awk.html –

+1

Działa to również na Mac OS. – bdemarest

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

Jest POSIX, więc powinien działać wszędzie.

Edytuj: Dodano -r zgodnie z sugestią Williama.

+0

+1, ale ... to się nie powiedzie, jeśli wejście zawiera "\". Użyj read -r –

0

Spróbuj tego:

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

Miałeś na myśli 'echo -e | wc -m', prawda? Bezużyteczne użycie poleceń; shell może zliczyć znaki w zmiennej. Plus 'echo -e' jest całkowicie niekompatybilny i działa w połowie powłok, podczas gdy zaczynając od jakiejś sekwencji ucieczki działa w innych i nic w pozostałych. –

+0

Tak, popraw ... błąd. Dziękuję za wskazanie. – Rahul

2

Oto przykład przy użyciu xargs:

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

To "echo%" nie obsługuje niebezpiecznych znaków, które wymagają cytowania z powłoki. Dodatkowo "xargs" podzieli Twój plik na spacje i znaki nowej linii, a nie tylko znaki nowej linii, tak jak zażądał tego oryginalny plakat. – bovine

1

Próbowałem innych odpowiedzi wymienione powyżej, ale są one bardzo dalekie od przyzwoitych rozwiązań gdy mamy do czynienia z dużymi plikami - zwłaszcza gdy rozmiar jednej linii zajmuje więcej niż ~ 1/4 dostępnej pamięci RAM.

Zarówno bash, jak i awk sypią całą linią, mimo że dla tego problemu nie jest potrzebna. Bash spowoduje błąd, gdy linia będzie zbyt długa, nawet jeśli masz wystarczająco dużo pamięci.

Wdrożyłem niezwykle prosty, dość niezoptymalizowany skrypt Pythona, który podczas testowania z dużymi plikami (~ 4 GB na linię) nie ulega slurpowi i jest zdecydowanie lepszym rozwiązaniem niż podane.

Jeśli jest to kod czasowo krytyczny dla produkcji, możesz przepisać pomysły w C lub wykonać lepszą optymalizację w wywołaniu odczytu (zamiast czytania tylko jednego bajtu na raz), po przetestowaniu, czy to rzeczywiście wąskie gardło.

Kod zakłada, że ​​znak nowej linii jest znakiem prostym, co jest dobrym założeniem dla systemu Unix, ale YMMV dla systemu Mac OS/Windows. Upewnij się, że plik kończy się na linii, aby mieć pewność, że liczba znaków ostatniego wiersza nie zostanie przeoczona.

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 
Powiązane problemy