используя sed, удалите только один символ перед совпадением чисел

#linux #bash #awk #sed

#linux #bash #awk #sed

Вопрос:

У меня есть текстовый файл, подобный этому:

 text-text-text-7.7.1-text
text-text-text-text-1.2.4-text
text-text-1.2.4-text
  

Я хочу заменить символ перед числами на пробел. Таким образом, ожидаемый результат должен быть

 text-text-text 7.7.1-text
text-text-text-text 1.2.4-text
text-text 1.2.4-text
  

Как бы я это сделал, используя sed?

Я пытался использовать sed -E ‘s/-/ / g’, но он заменяет все — пробелами

 text text text 7.7.1 text
text text text text 1.2.4 text
text text 1.2.4 text
  

а также sed -E ‘s/-[0-9]/ /g’ и вывод выглядит следующим образом:

 text-text-text .7.1-text
text-text-text-text .2.4-text
text-text .2.4-text
  

Как мне это исправить?

Ответ №1:

Поскольку вам нужно только одно применение правила, не используйте final /g . И чтобы применять замену только при наличии следующего числа, вы должны включить это в правило сопоставления:

 sed 's/-([0-9])/ 1/'
  

Поскольку вы не хотите, чтобы фактическая цифра заменялась, приведенное выше выражение фиксирует ее в группе (...) и повторно вставляет через 1 выражение.

Ответ №2:

Поскольку вы отметили свой вопрос awk , это задача для gensub. Пусть data.txt будет имя вашего файла, тогда вы делаете:

 awk '// {print gensub(/-([0-9])/, " \1", 1)}' data.txt
  

получение выходных данных:

 text-text-text 7.7.1-text
text-text-text-text 1.2.4-text
text-text 1.2.4-text
  

Это использует группу захвата и ссылку на нее в ответе @Thomas, подобном замене, и заменяет первое появление. Стоит отметить, что gensub это позволяет вам легко изменять любое вхождение — если вы укажете 2 в качестве 3-го аргумента, он заменит 2-е вхождение и так далее.