Я хотів би надрукувати кількість символів у кожному рядку текстового файлу за допомогою команди unix. Я знаю, що з PowerShell це просто
gc abc.txt | % {$_.length}
але мені потрібна команда unix.
Відповіді:
Використовуйте Awk.
awk '{ print length }' abc.txt
while IFS= read -r line; do echo ${#line}; done < abc.txt
Це POSIX, тому він повинен працювати скрізь.
Редагувати: Додано -r, як запропонував Вільям.
Редагувати: Остерігайтеся обробки Unicode. Bash і zsh, з правильно встановленою мовою, відображатимуть кількість кодових точок, але тире - байти - тому вам доведеться перевірити, що робить ваша оболонка. І тоді в Unicode є багато інших можливих визначень довжини, тож це залежить від того, що ви насправді хочете.
Редагувати: префікс з, IFS=
щоб уникнути втрати пробілів на початку та в кінці.
IFS=
на read
команду , коли потрібно , щоб читати в довільних даних. Отже IFS= read -r
. read
використовує IFS
для розбиття слів, і хоча всі розбиті слова потім вставляються назад в одну доступну змінну ( line
), немає гарантії, що вони будуть вставлені назад разом із усіма оригінальними символами-роздільниками, які вони мали, або лише одним потенційно різним ті. Наприклад, за замовчуванням IFS, рядок foo bar
може стати foo bar
, втративши 7 пробілів. (На зразок того, як у цьому коментарі Stack Overflow втратив сусідні пробіли в цьому прикладі рядка).
IFS
слід встановити, але проблема, коли це не так, є більш тонкою.
Я спробував інші відповіді, перераховані вище, але вони дуже далекі від гідних рішень при роботі з великими файлами - особливо, коли розмір одного рядка займає більше ~ 1/4 доступної оперативної пам'яті.
І bash, і awk скрупують весь рядок, хоча для цієї проблеми це не потрібно. Bash помилиться, якщо рядок буде занадто довгим, навіть якщо у вас достатньо пам'яті.
Я реалізував надзвичайно простий, досить неоптимізований скрипт python, який при тестуванні з великими файлами (~ 4 ГБ на рядок) не викликає непорозумінь і є набагато кращим рішенням, ніж подані.
Якщо це критично важливий для часу код для виробництва, ви можете переписати ідеї на C або виконати кращі оптимізації прочитаного виклику (замість того, щоб читати лише один байт за раз), протестувавши, що це справді вузьке місце.
Код передбачає, що новий рядок є символом подачі лінії, що є гарним припущенням для Unix, але YMMV для Mac OS / Windows. Переконайтеся, що файл закінчується подачею рядків, щоб переконатися, що кількість символів останнього рядка не пропущена.
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
Ось приклад використання xargs
:
$ xargs -d '\n' -I% sh -c 'echo % | wc -c' < file
Спробуйте це:
while read line
do
echo -e |wc -m
done <abc.txt
echo -e | wc -m
, чи не так? Це марне використання команд; оболонка може рахувати символи у змінній. Плюс echo -e
абсолютно несумісний і працює в половині снарядів, а починаючи з якоїсь послідовності втечі працює в деяких інших, а в решті нічого.