Bir metin dosyasının her satırındaki karakter sayısını bir unix komutu kullanarak yazdırmak istiyorum. Powershell ile bunun basit olduğunu biliyorum
gc abc.txt | % {$_.length}
ama unix komutuna ihtiyacım var.
Yanıtlar:
Awk kullanın.
awk '{ print length }' abc.txt
while IFS= read -r line; do echo ${#line}; done < abc.txt
POSIX olduğundan her yerde çalışmalıdır.
Düzenleme: William tarafından önerildiği gibi -r eklendi.
Düzenleme: Unicode işlemeye dikkat edin. Bash ve zsh, doğru bir şekilde ayarlanmış yerel ayar ile kod noktalarının sayısını gösterir, ancak tire baytları gösterir - bu nedenle kabuğunuzun ne yaptığını kontrol etmeniz gerekir. Ve sonra Unicode'da zaten birçok olası uzunluk tanımı var, bu yüzden gerçekte ne istediğinize bağlı.
Düzenle: IFS=
Baştaki ve sondaki boşlukları kaybetmemek için önek ile .
IFS=
üzerinde read
keyfi veri okumak isteyen zaman komuta. Yani IFS= read -r
. kelime bölme yapmak için read
kullanır ve IFS
tüm bölünmüş kelimeler daha sonra mevcut tek bir değişkene ( line
) tekrar yapıştırılsa bile, sahip oldukları tüm orijinal ayırıcı karakterlerle veya potansiyel olarak farklı yalnızca biriyle tekrar yapıştırılmalarının garantisi yoktur. olanlar. Örneğin, varsayılan IFS ile satır 7 boşluk kaybederek foo bar
haline gelebilir foo bar
. (Stack Overflow'un bu açıklamadaki örnek dizedeki bitişik boşlukları nasıl kaybettiği gibi).
IFS
ayarlanmalısın, ama sorun olmadığında daha ince.
Yukarıda listelenen diğer cevapları denedim, ancak büyük dosyalarla uğraşırken iyi çözümlerden çok uzaktalar - özellikle tek bir satırın boyutu mevcut RAM'in ~ 1 / 4'ünden fazlasını kapladığında.
Hem bash hem de awk, bu problem için gerekli olmamasına rağmen tüm satırı karıştırır. Yeterli belleğiniz olsa bile, bir satır çok uzun olduğunda Bash hata verir.
Son derece basit, oldukça optimize edilmemiş bir python betiği uyguladım, büyük dosyalarla (satır başına ~ 4 GB) test edildiğinde höpürdetmiyor ve verilenlerden çok daha iyi bir çözüm.
Bu, üretim için zaman açısından kritik kodsa, bunun gerçekten bir darboğaz olduğunu test ettikten sonra, fikirleri C'de yeniden yazabilir veya okuma çağrısında daha iyi optimizasyonlar gerçekleştirebilirsiniz (bir seferde yalnızca tek bir bayt okumak yerine).
Kod, yeni satırın bir satır besleme karakteri olduğunu varsayar, bu Unix için iyi bir varsayımdır, ancak Mac OS / Windows'ta YMMV. Son satır karakter sayısının gözden kaçırılmamasını sağlamak için dosyanın bir satır besleme ile bittiğinden emin olun.
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
İşte kullanım örneği xargs
:
$ xargs -d '\n' -I% sh -c 'echo % | wc -c' < file
Bunu dene:
while read line
do
echo -e |wc -m
done <abc.txt
echo -e | wc -m
istedin, değil mi? Komutların gereksiz kullanımı; kabuk bir değişkendeki karakterleri sayabilir. Artı echo -e
tamamen uyumsuzdur ve mermilerin yarısında çalışır, bazı kaçış sekansıyla başlarken bazılarında çalışır, diğerlerinde hiçbir şey olmaz.