Как транслитерировать некоторые символы с 1 -по -1, оставить некоторые без изменений и заменить другие теми же целевыми символами?

В относительно недавних версиях procps вы можете использовать etimesв качестве прошедшего времени в секундах:

ps -Ao etimes= -o pid= |
  awk -v n=30 '$1 >= n*86400 {print $2}' |
  xargs -r kill

(здесь предполагается GNU xargsдля его -rопции)

Или:

ps -Ao etimes= -o pid= |
  awk -v n=30 '$1 >= n*86400 {print "kill", $2}' |
  sh

В более старых версиях вы можете вернуться кetime:

LC_ALL=C ps -Ao etime= -o pid= |
  awk -v n=30 '$1 ~ /^[[:digit:]]+-/ && 0+$1 >= n {print "kill", $2}' |
  sh

(этот синтаксис соответствует POSIX и должен работать во всех системах, совместимых с POSIX ).

4
23.09.2021, 13:26
4 ответа

Я предлагаю этот perlвариант:

$ perl -pe 's/(?![MALCREX])[A-Z]/_/g;y/MALCREX/THEOFIS/' file 
THE __FF_I__ OF THE F_____E IS THE ___ _HI F_O_ "THE HO_HEFT __I__E__E OF TI __I_ TH_T _E __E F___I___E_ __ __FTE__"

Он выполняет предварительное утверждение, находя все символы в диапазоне A-Z, кроме MALCREX. Затем выполняет подстановку, как в вашей команде sed.

Как прокомментировал Stéphane Chazelas , это решение имеет то преимущество, что [A-Z]можно заменить на \wили\pL(и, возможно, добавить -Mopen=localeдля обработки всех символов в локали. ), поэтому он может обрабатывать все виды писем.


Другой подход предложен в комментарии дяди Билли:

perl -pe y/MALCREXA-Z/THEOFIS_/
5
23.09.2021, 15:52

Используя perl :, как рекомендовано в комментариях @ImHere, добавляется опция -C для поддержки unicode.

perl -C -pe  's{\w+}{$& =~ tr/MALCREX/_/cr =~ y/MALCREX/THEOFIS/r}ge' file

Другим способом может быть:

perl -pe 's{\w}{tr/MALCREX/THEOFIS/||s/./_/ for$a=$&;$a}ge' file

GNU sed может сделать это (изменить \w ---> [[ :upper :]] )если вы хотите поведение POSIX плюс измените \n справа от s/// к буквальному экранированному переводу строки.

sed -e '
  s/\w/&\n/g
  s/[^MALCREX]\n/_/g
  y/MALCREX/THEOFIS/
  s/\n//g
' file

GNU-сед

sed -Ee '
  s/[MALCREX]/&\n/g
  :a
    s/[A-Z]([^\n]|$)/_\1/
  ta
  y/MALCREX/THEOFIS/
  s/\n//g
' file
4
23.09.2021, 19:48

Немного длиннее, чем пара других предложений, но, возможно, проще для понимания.

Первое предложение :сопоставить нежелательные алфавиты с _, а затем транспонировать оставшийся набор.

tr BDFGHIJKNOPQSTUVWYZ _ <file | tr MALCREX THEOFIS
THE __FF_I__ OF THE F_____E IS THE ___ _HI F_O_

Второе предложение :сделать все это в одной команде. (GNU и BSD trнеявно повторяют последний символ цели замены(_)по мере необходимости для всех неотображенных символов в исходной карте замены, но это поведение отмечено POSIX просто как не указано .)

tr MALCREXBDFGHIJKNOPQSTUVWYZ THEOFIS_ <file
THE __FF_I__ OF THE F_____E IS THE ___ _HI F_O_
6
23.09.2021, 21:47

Использование Raku (, ранее известного как Perl _6)

raku -pe 'tr/MALCREX/THEOFIS/; s:g/ <+:Uppercase_Letter - [THEOFIS]> /_/;' 

Пример ввода:

MAL TIRRUEZF CR MAL RKZYIOL EX MAL OIY UAE RICF "MAL ACWALRM DYEUPLFWL CR ME DYEU MAIM UL IZL RKZZEKYFLF GH OHRMLZH"

Пример вывода (запуск кода Raku вверху):

THE TIFF_I_F OF THE F___IOE IS THE OI_ _HI FIOF "THE HO_HEFT __I__EF_E OF TI __I_ THIT _E I_E F___I__FEF _H OHFTE_H"

Одним из преимуществ Raku для решения этого вопроса является то, что Unicode поддерживается по умолчанию (, но не рассматривается в этом ответе ).

Второй оператор в приведенном выше коде использует глобальную замену s///с заданным классом символов <+:Uppercase_Letter - [THEOFIS]>, который может быть выражен более просто как <+:Lu - [THEOFIS]>. Как отметил @Stéphane Chazelas в комментариях, :Luможно заменить на :Letterили [\w], чтобы он мог обрабатывать все виды букв.

Для простого случая, представленного (только "двойными кавычками и пробелами без -alnum символов ), второе выражение в приведенном выше коде может быть записано с использованием tr///с наречием :complement. Оператор tr:c/THEOFIS" /_/;добавляет "двойных кавычек и пробелов в список THEOFIS. (Другими словами, 'Возьмите:complementвсех символов между первыми двумя/…/и измените их на символ, указанный между вторыми двумя /…/, который в данном случае_подчеркивать.')

raku -pe 'tr/MALCREX/THEOFIS/; tr:c/THEOFIS" /_/;' 

Пример вывода:

THE TIFF_I_F OF THE F___IOE IS THE OI_ _HI FIOF "THE HO_HEFT __I__EF_E OF TI __I_ THIT _E I_E F___I__FEF _H OHFTE_H"

РЕДАКТИРОВАНО:

Разделение транслитерации на два этапа, как я сделал выше, означает, что я рискую перезаписать «последний» символ на втором этапе. Чтобы избежать этого, я могу преобразовать символы в нижний регистр на обоих этапах, что дает тот же результат, что и другие (, но --см. ниже ).

Наконец, похоже, что ОП допустил ошибку в опубликованной таблице транслитерации, поскольку обновленная таблица/код (ниже )дает гораздо более разумный вывод:

raku -pe 'tr/MALCREX/theisof/; tr:c/theisof" /_/;'

Обновлен вывод:

the __ss_o__ is the s_____e of the ___ _ho s_i_ "the hi_hest __o__e__e is to __o_ th_t _e __e s___o___e_ __ __ste__"

https://docs.raku.org/language/regexes#Predefined_character_classes
https://raku.org

1
25.09.2021, 19:34

Теги

Похожие вопросы