Как я могу использовать sed для замены определенного шаблона и добавления исключений в ту же строку?

Я использую sed для поиска и замены шаблона.

Мой шаблон - «-»

У меня есть следующие данные

>1-2-3-4-5 29238232382083e-9  
>1-2-3-4-5    29238232382083e-9   
>1-2-3-4-5    29238232382083e-9   
>1-2-3-4-5    29238232382083e-9     

Я хочу заменить «-» в 1-2-3-4-5 на «*», чтобы получить 1 * 2 * 3 * 4 * 5

Однако, когда я делаю замену на
sed -i -e '/ - / * / g

затрагиваются все символы «-», даже 29238232382083e-9, которые оказываются 29238232382083e * 9.

Что я мог сделать, чтобы заменить все «-», кроме «-», которые расположены после «e», как в этом случае 29238232382083e-9?

-1
29.06.2017, 03:12
3 ответа

Выберите один:

awkподход:

awk '{ gsub("-","*",$1) }1' OFS='\t' file
  • gsub("-","*",$1)- заменить все -с *в 1-м поле

perlподход:

perl -lae '$,="\t"; $F[0] =~ y/-/*/; print @F' file
  • -a- авторазбиение $_в массив @F

  • $,="\t"- объединить поля с \t(вкладка)

  • $F[0] =~ y/-/*/- перевести все -до *в 1-м поле $F[0]

Вывод (для подходов awkи perl):

>1*2*3*4*5  29238232382083e-9
>1*2*3*4*5  29238232382083e-9
>1*2*3*4*5  29238232382083e-9
>1*2*3*4*5  29238232382083e-9

sedподхода:

sed 'h; s/ .*$//; y/-/*/;G; s/\n[^[:space:]]*//' file

Вывод (для sedподхода):

>1*2*3*4*5 29238232382083e-9  
>1*2*3*4*5    29238232382083e-9   
>1*2*3*4*5    29238232382083e-9   
>1*2*3*4*5    29238232382083e-9
1
28.01.2020, 05:07
sed 's/\([^e]\)-/\1*/g' /path/to/input

Чтобы уточнить sedутверждение:

  • \([^e]\)-Здесь мы используем группировку для поиска любого символа, кроме e, за которым следует дефис
  • \1*-Здесь мы заменяем то, что было найдено, тем, что было в этой группе (i. г. не -e перед дефисом ), за которым следует звездочка, заменяющая этот дефис.

Обратите внимание, что это не будет работать с дефисами, которые являются первым символом строки; для этого нам придется добавить специальный случай:

sed 's/\([^e]\)-/\1*/g;s/^-/*/' /path/to/input

Это аналогично, но вместо дефиса, который является первым символом строки, используется звездочка. Так как это первый символ, ему не может предшествовать e.

2
28.01.2020, 05:07

Хотя это можно сделать с помощью POSIX sed, но здесь это показано с использованием GNU sed из-за простых выражений:

sed -e '
   s/\S\s/&\n/;:a
   s/-\(.*\)/*\1/;ta
   s/\n//
' yourfile

Результаты

>1*2*3*4*5 29238232382083e*9
>1*2*3*4*5    29238232382083e*9
>1*2*3*4*5    29238232382083e*9
>1*2*3*4*5    29238232382083e*9

Пояснение

  • Отметьте границу, где мы хотим, чтобы произошли изменения.
  • Затем мы настраиваем цикл и постепенно вносим в него изменения.
0
28.01.2020, 05:07

Теги

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