Могут ли команды tr быть закодированы, чтобы избежать нескольких tr процессов в конвейере?

У меня есть куча txt-файлов, я хотел бы выводить их с нижним, только буквенным и одним словом на строку, я могу сделать это с несколькими tr командами в конвейере вроде этого:

 tr -d '[:punct:]' <doyle_sherlock_holmes.txt | tr '[:upper:]' '[:lower:]' | tr ' ' '\n' 

Можно ли сделать это одним сканированием? Я мог бы написать программу на C, чтобы сделать это, но я чувствую, что есть способ сделать это, используя tr , sed , awk или perl .

3 Solutions collect form web for “Могут ли команды tr быть закодированы, чтобы избежать нескольких tr процессов в конвейере?”

Вы можете комбинировать несколько переводов (за исключением сложных случаев, связанных с перекрывающимися языковыми зависимыми наборами), но вы не можете объединить удаление с переводом.

 <doyle_sherlock_holmes.txt tr -d '[:punct:]' | tr '[:upper:] ' '[:lower:]\n' 

Два вызова tr , вероятно, будут быстрее, чем один вызов более сложных инструментов, но это очень зависит от размера ввода, от пропорций разных символов, от реализации tr и конкурирующих инструментов, от операционной системы, от количество ядер и т. д.

Вот несколько подходов:

  • GNU grep и tr : найти все слова и сделать их нижним регистром

     grep -Po '\w+' file | tr '[AZ]' '[az]' 
  • GNU grep и perl: как указано выше, но perl обрабатывает преобразование в нижний регистр

     grep -Po '\w+' file | perl -lne 'print lc()' 
  • perl: найти все алфавитные символы и напечатать их в нижнем регистре (спасибо @steeldriver):

     perl -lne 'print lc for /[az]+/ig' file 
  • sed: удалите все символы, которые не являются алфавитами или пробелами, замените все буквенные символы их нижестоящими версиями и замените все пробелы символами новой строки. Обратите внимание, что это предполагает, что все пробелы являются пробелами, без вкладок.

     sed 's/[^a-zA-Z ]\+//g;s/[a-zA-Z]\+/\L&/g; s/ \+/\n/g' file 

Да. Вы можете сделать это w / tr в локали ASCII (что для GNU tr любом случае является своеобразным видом) . Вы можете использовать классы POSIX, или вы можете ссылаться на байтовые значения каждого символа на восьмеричное число. Вы также можете разделить свои преобразования по диапазонам.

 LC_ALL=C tr '[:upper:]\0-\101\133-140\173-\377' '[:lower:][\n*]' <input 

Вышеприведенная команда преобразует все символы верхнего регистра в нижний регистр, полностью игнорирует строчные буквы и преобразует все остальные символы в новые строки. Конечно, тогда вы заканчиваете тонну пустых линий. В этом случае может оказаться полезным переключатель повторов tr -s quizze, но если вы используете его вместе с преобразованием [:upper:] to [:lower:] то вы также сжимаете символы верхнего регистра. Таким образом, по-прежнему требуется второй фильтр, например …

 LC... tr ... | tr -s \\n 

…или…

 LC... tr ... | grep . 

… и поэтому он становится намного менее удобным, чем делать …

 LC_ALL=C tr -sc '[:alpha:]' \\n <input | tr '[:upper:]' '[:lower:]' 

… который сжимает -c дополнение к алфавитным символам посредством последовательности в одну новую строку, а затем выполняет верхнее и нижнее преобразование на другой стороне трубы.

Это не значит, что диапазоны такого рода не полезны. Например:

 tr '\0-\377' '[1*25][2*25][3*25][4*25][5*25][6*25][7*25][8*25][9*25][0*]' </dev/random 

… может быть очень удобной, так как она преобразует входные байты во все цифры по расширенному спектру их значений. Не тратьте, не хотите, вы знаете.

Другой способ сделать преобразование может включать dd .

 tr '\0-\377' '[A*64][B*64][C*64][D*64]' </dev/urandom | dd bs=32 cbs=8 conv=unblock,lcase count=1 dadbbdbd ddaaddab ddbadbaa bdbdcadd 

Поскольку dd может одновременно выполнять как unblock и преобразование lcase , возможно, даже удастся передать большую часть работы. Но это может быть действительно полезно, если вы можете точно предсказать количество байтов на слово – или, по крайней мере, можете заранее заполнить каждое слово пробелами до прогнозируемого количества байтов, потому что unblock ест конечные пробелы в конце каждого блока.

  • Как удалить пробелы в столбцах?
  • Как работает «-dc» в «cat / dev / urandom | tr -dc "01"?
  • Могу ли я использовать `sed` для перевода символов, например, с помощью` tr`?
  • Есть ли библиотека или инструмент для «перевода» строки с одного раскладки клавиатуры на другой?
  • Почему команда tr не читается из файла?
  • Говоря «tr», что az - это не только ASCII
  • tr не заменяет апостроф
  • Перенаправление tr stdout в файл
  • Итерировать файлы в папке
  • «Тюнинг» выражения tr и sed
  • Сделать статистику биграмм
  • Interesting Posts

    bashrc PS1: пользовательская подсказка не очистит весь текст

    Условно установите раздел Windows

    В правилах udev назначается одинаковое имя порта для модема с 4 портами ttyUSB

    Как автоматически войти в систему с пользователем root в Fedora?

    команда не найдена, присваивая значение массиву в bash

    Уменьшение числа с помощью sed

    Могу ли я изменить шрифт терминала?

    Извлечение широты / долготы из изображения с использованием завитка

    Как использовать клавишу right-Alt вместо клавиши left-Alt

    Протрите диск Solaris

    Безопасное удаленное резервное копирование с использованием дублирования

    Diff, действующий очень странно, сообщает, что длинные блоки удалены, когда короткие биты по всему блоку были изменены, удалены или добавлены

    Можно ли каждый день перезапускать cron?

    Эффективное удаление заголовка на месте для больших файлов с помощью sed?

    Удалить строки, которые соответствуют точно и только строке

    Linux и Unix - лучшая ОС в мире.