sed находит и заменяет строку, окруженную выводом [] в файл - PullRequest
1 голос
/ 24 апреля 2020

Иметь файл со следующим

"SCAN_IN[0]" : input;

Хотите использовать sed для поиска и замены на scan_0

Я использую следующую команду

sed  's/SCAN_IN[]0[]/scan_0/' fileA > fileB

Это это то, что я получаю

"scan_00]" : input;

Я хочу

"scan_0" : input;

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Шаблон SCAN_IN[]0[] сначала соответствует SCAN_IN, а затем []0[] соответствует одному символу: либо ], либо 0, либо [ (из-за "умного размещения", когда находящийся без экранирования ] находится сразу после открывающей скобки выражение [ (или [^, если это выражение с отрицательной скобкой) рассматривается как литерал ], а не как символ выражения закрывающей скобки).

В вашей строке SCAN_IN[]0[] соответствует SCAN_IN[ и, следовательно, результатом замены будет scan_0 0]" : input;.

Вы можете использовать

sed 's/SCAN_IN\[0]/scan_0/' fileA > fileB

См. онлайн sed демо :

s='"SCAN_IN[0]" : input;'
sed 's/SCAN_IN\[0]/scan_0/'  <<< "$s"
# => "scan_0" : input;
0 голосов
/ 24 апреля 2020

Я сделаю несколько предположений:

Вы хотите заменить "SCAN_IN[?]" на "scan_?", где ? может быть любой строкой (ноль или более) последовательных не символы закрывающей скобки. Это означает три вещи (по крайней мере): что вы должны конвертировать из верхнего регистра на входе в нижний регистр на выходе (что довольно странно); что двойные кавычки являются частью соответствующего шаблона - так что сопоставляется только SCAN_IN, но не, например, RE SCAN_IN; и что вы хотите, чтобы это было сделано для всего, что находится в скобках, а не только для одного символа 0.

Кроме того, вам все равно, где появляется шаблон (будь то перед дополнительным текстом, например : input или где-либо еще). еще), и вы должны сделать то же самое изменение, даже если шаблон появляется более одного раза в одной строке. (Поэтому нам нужен флаг g.)

Команда sed, которая может сделать все, что:

sed -E 's/"SCAN_IN\[([^]]+)]"/"scan_\1"/g'

Вот несколько примеров:

$ echo '"SCAN_IN[0]" : input' | sed -E 's/"SCAN_IN\[([^]]*)]"/"scan_\1"/g'

"scan_0" : input


$ echo '"TO_SCAN_IN[0]" : input' | sed -E 's/"SCAN_IN\[([^]]*)]"/"scan_\1"/g'

"TO_SCAN_IN[0]" : input



$ echo '"SCAN_IN[0]" : input "RESCAN_IN[1]" "SCAN_IN[37]" "SCAN[0]"' | 
                                 sed -E 's/"SCAN_IN\[([^]]+)]"/"scan_\1"/g'

"scan_0" : input "RESCAN_IN[1]" "scan_37" "SCAN[0]"
...