Linux: подсчет пробелов и других символов в файле - PullRequest
2 голосов
/ 30 декабря 2011

Проблема:

Мне нужен точный формат для программы почтового автомата.Ожидается определенный формат.Я могу посчитать количество новых строк, возврат каретки, вкладки ... и т. Д.используя такие инструменты, как

cat -vte

и

od -c

и

wc -l ( or wc -c )

Однако я хотел бы знать точное количество начальных и конечных пробелов между символамии разделы текста.Вкладки также.

Вопрос:

Как вы будете анализировать, а затем точно сопоставлять шаблон, используя обычные инструменты Unix + Perl или Python?Однострочники предпочтительнее.Кроме того, что вы посоветуете для соответствия файла в кодировке DOS?Вы бы сначала перевели его в NIX, а затем проанализировали или оставили, как есть?

ОБНОВЛЕНИЕ

Используя это, чтобы увидеть отдельные пробелы [не предполагается, что символы '%' вfile]:

sed 's/ /%/g' filename.000

Планирование создания сценария, который анализирует вкладку каждой строки и содержимое пробела.

Использование решения @ shiplu с указанием на толпу против кошек:

while read l;do echo $l;echo $((`echo $l |  wc -c` - `echo $l | tr -d ' ' | wc -c`));done<filename.000

Все еще требуются некоторые настройки для Windows, но все идет хорошо.

SAMPLE TEXT

Ключ для чтения:

отмечены новые строкис \ n

Возврат каретки, помеченный \ r

Неизвестные символы пробела / табуляции, помеченные [: пробел:] (нужно их учитывать)

\r\n
\n
[:space:]Institution Anon LLC\r\n
[:space:]123 Blankety St\r\n
[:space:]Greater Abyss, AK  99999\r\n
\n
\n
[:space:]                                10/27/2011\r\n
[:space:]Requested materials are available for pickup:\r\n
[:space:]e__\r[:space:]                     D_ \r[:space:]   _O\r\n
[:space:]Bathtime for BonZo[:space:]       45454545454545[:space:]  10/27/2011\r\n
[:space:]Bathtime for BonZo[:space:]       45454545454545[:space:]  10/27/2011\r\n
\n
\n
\n
\n
\n
\n
[:space:]                             Pantz McManliss\r\n
[:space:]                             Gibberish Ave\r\n
[:space:]                             Northern Mirkwood, ME  99999\r\n
( untold variable amounts of \n chars go here )

ОБНОВЛЕНИЕ 2

Использование IFS с чтением дает результаты, подобные рубину, опубликованному кем-то ниже.

while IFS='' read -r line
 do 
     printf "%s\n" "$line" | sed 's/ /%/g' | grep -o '%' | wc -w
 done < filename.000

Ответы [ 7 ]

5 голосов
/ 31 декабря 2011
perl -nlE'say 0+( () = /\s/g );'

В отличие от принятого в настоящее время ответа, он не разбивает ввод на поля, отбрасывая результат. Также не нужно создавать массив просто для подсчета количества значений в списке.

Используемые идиомы:

  • 0+( ... ) налагает скалярный контекст наподобие scalar( ... ), но он более понятен, потому что сообщает читателю ожидаемое число.
  • Присвоение списка в скалярном контексте возвращает количество элементов, возвращаемых его RHS, поэтому 0+( () = /.../g ) дает количество совпадений () = /.../g.
  • -l при использовании с -n приведет к тому, что вход будет «раздроблен», так что это удалит перевод строки из счетчика.

Если вас интересуют только пробелы (U + 0020) и табуляции (U + 0009), следующее быстрее и проще:

perl -nE'say tr/ \t//;'

В обоих случаях вы можете передать ввод через STDIN или через файл, названный аргументом.

4 голосов
/ 30 декабря 2011

Регулярные выражения в Perl или Python могли бы быть здесь.

Да, для изучения "perl, schmerl, zwerl" может потребоваться первоначальное вложение времени, но как только вы приобретете опытс помощью чрезвычайно мощного инструмента, такого как регулярные выражения, он может сэкономить вам огромное количество времени в будущем.

enter image description here

2 голосов
/ 31 декабря 2011
perl -nwE 'print; for my $s (/([\t ]+)/g) { say "Count: ", length $s }' input.txt

Это будет подсчитывать отдельные группы табуляции или пробела вместо того, чтобы считать все пробелы во всей строке. Например:

    foo        bar

Распечатает

    foo        bar
Count: 4
Count: 8

Вы можете пропустить отдельные пробелы (пробелы между словами). То есть не считайте пробелы в Bathtime for BonZo. Если это так, замените + на {2,} или любой другой минимум, который вы считаете подходящим.

2 голосов
/ 31 декабря 2011

подсчет пробелов:

sed 's/[^ ]//g' FILE | tr -d "\n" | wc -c

до, позади и между текстом.Вы хотите рассчитывать переводы строк, табуляции и т. Д. Одновременно и суммировать их, или как отдельный шаг?

1 голос
/ 31 декабря 2011

В случае, если Ruby имеет значение (он делает count :)

ruby -lne 'puts scan(/\s/).size'

и теперь немного Perl (немного менее интуитивно понятное ИМХО):

perl -lne 'print scalar(@{[/(\s)/g]})'

1 голос
/ 31 декабря 2011

Если вы хотите посчитать количество space с в pm.txt, эта команда сделает,

 cat pm.txt | while read l; 
 do echo $((`echo $l |  wc -c` - `echo $l | tr -d ' ' | wc -c`));
 done;

Если вы хотите посчитать количество space с, \r, \n, \t используйте это,

cat pm.txt | while read l;
do echo $((`echo $l |  wc -c` - `echo $l | tr -d ' \r\n\t' | wc -c`));
done;

read удалит любых ведущих символов. Если вы не хотите этого, есть неприятный способ. Сначала разбейте ваш файл так, чтобы в каждом файле было только 1 строка, используя

`split -l 1 -d pm.txt`. 

После этого будет куча x* файлов. Теперь пройдитесь по нему.

for x in x*; do echo $((`cat $x |  wc -c` - `cat $x | tr -d ' \r\n\t' | wc -c`)); done;

Удалите эти файлы с помощью rm x*;

0 голосов
/ 30 декабря 2011

Если вы спросите меня, я напишу простую программу на C, которая сделает подсчет и форматирование всего за один раз. Но это только я. К тому времени, как я закончил бродить с perl, schmerl, zwerl, я бы потратил впустую полдня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...