как использовать tr для замены нескольких наборов?

Вам не нужно использовать catс grep, и вы можете сгруппировать команды, чтобы поместить туда перенаправление только один раз:

{
  grep OpenFin < LoginExInternal.txt && echo 
  grep Chrome < LoginExInternal.txt && echo
  grep memoryInfo:jsHeapSizeLimit:1 < MemoryUnderThreshold.txt && echo
} >> LoginExcInternal.txt

Также обратите внимание, что если вы объедините все команды с помощью &&, то сбой grep остановит выполнение следующих echo, а также остальных greps. Это может быть или не быть тем, что вы хотите. Использование только grep && echo, как указано выше, приведет к запуску всех grepв любом случае, но печатать дополнительные новые строки только тогда, когда grepсоответствует чему-то.

Кроме того, я не совсем уверен, как обрабатываются разрывы строк в cygwin, то есть требуется ли явный вывод возврата каретки $'\r'.

3
18.06.2020, 20:28
4 ответа

Предположим, что диапазоны равны 0 -4 и 5 -9:

tr 0-9 AAAAAB

или

sed y_0123456789_AAAAABBBBB_
1
18.03.2021, 23:27

Примените замену глобально ко всем символам, используя квантификатор /gв конце. Без него замена заканчивается на первом совпавшем символе и не будет продолжаться впоследствии.

Еще один способ использования sedдля транслитерации символов (аналогичныйtr)доступен как в GNU, так и в POSIX

sed 'y/123456789/AAAAABBBB/'
4
18.03.2021, 23:27

POSIXly:

tr 0123456789  AAAAAABBBB
tr 0123456789 '[A*6][B*4]'
tr 0123456789 '[A*6][B*]'
sed 's/[012345]/A/g; s/[6789]/B/g'
sed 'y/0123456789/AAAAAABBBB/'

Несколько замечаний:

  • tr 012345 Aне соответствует POSIX, так как второй набор не имеет того же размера, что и первый.
  • tr 0-5 AAAAAAгарантированно работает только в локали POSIX/C.
  • то же самое для sed 's/[0-5]/A/g', где [0-5]может соответствовать гораздо большему, чем 012345, в локалях, отличных от -POSIX.

Обратите внимание, что по состоянию на 2020 год реализация GNU tr, в отличие от реализации GNU sed, не поддерживает работу с несколькими -байтами (, хотя я полагаю, что существуют некоторые исправления, которые добавляют некоторый уровень поддерживают ), поэтому подходы trнельзя использовать в системе GNU в локалях, использующих наборы символов, такие как GB18030, где кодировка большинства символов содержит кодировку десятичных цифр.

Например:

$ printf '%s\n' "$LANG"
zh_CN.gb18030
$ locale charmap
GB18030
$ locale title
Chinese locale for Peoples Republic of China
$ tr --version
tr (GNU coreutils) 8.30
[...]
$ sed --version
sed (GNU sed) 4.7
[...]

$ echo '£12' | tr 0123456789 '[A*6][B*4]'
丄凙AA
$ echo '£12' | sed 'y/0123456789/AAAAAABBBB/'
£AA

Это потому, что£(символ британского фунта стерлингов )закодирован как байты 0x81 0x30 0x84 0x35, где 0x30 также является кодировкой 0, а 0x35 — кодировкой 5:

.
$ echo '£12' | LC_ALL=C od -vtx1 -tc
0000000  81  30  84  35  31  32  0a
        201   0 204   5   1   2  \n
0000007
$ echo '£12' | tr 0123456789 '[A*6][B*5]' | LC_ALL=C od -vtx1 -tc
0000000  81  41  84  41  41  41  0a
        201   A 204   A   A   A  \n
0000007
2
18.03.2021, 23:27

С sedвам нужно добавить g, чтобы заменить все вхождения в каждой строке:

sed 's/[0-4]/A/g;s/[5-9]/B/g'

С помощью trвы можете связать два trс:

tr '0-4' A | tr '6-9' B

или укажите явное преобразование символов:

tr 0123456789 AAAAABBBBB

или даже:

tr 0-45-9 AAAAABBBBB

(но я нахожу последнее менее читаемым, так как отображение 1 -1 не сразу видно ).

Повторяющиеся Bs можно сокращать(trпри необходимости повторять последний символ ), а диапазоны можно объединять:

tr 0123456789 AAAAAB
tr 0-9 AAAAAB

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

tr 0123456789 \
   AAAAABBBBB

или, воспользовавшись тем фактом, что диапазоны в кавычках соответствуют расширенным длинам в этом сценарии:

tr '0-4''5-9' \
   AAAAABBBBB

Я предполагаю, что разделение диапазона равно 0 -4 и 5 -9, чтобы разделить поровну, как в первой команде вашего примера sed. Диапазоны могут быть скорректированы по мере необходимости.

8
18.03.2021, 23:27

Теги

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