grep в sed, добавить после совпадения строк, но вместо этого в конце строки

#bash #sed

#bash #sed

Вопрос:

У меня есть следующий текстовый файл со следующими строками:

 <test="123">
<test="456">
<test="789">
  

Моя цель — добавить к приведенному выше текстовому файлу ключевое слово «HELLO» после приведенных выше чисел следующим образом:

   <test="123.HELLO">
  <test="456.HELLO">
  <test="789.HELLO">
  

с помощью команды grep и cut мне удается получить значение между кавычками.

 grep -o "test=".* test.txt | cut -d " -f2
  

Я попытался использовать sed поверх него, с этой строкой

 grep -o "test=".* test.txt | cut -d " -f2 | sed -i -- 's/$/.HELLO/' test.txt
  

однако самое близкое, что мне удается получить, — это «.HELLO», который добавляется непосредственно в конец строки (а не после чисел между кавычками)

 <test="123">.HELLO 
<test="456">.HELLO 
<test="789">.HELLO
  

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

Комментарии:

1. можете ли вы уточнить: 1) пробелы перед ожидаемыми выходными строками необходимы или неверно показаны здесь из-за форматирования 2) содержит ли ваш входной файл строки, не содержащие test= ? если да, должны ли они также быть частью вывода

Ответ №1:

Вы можете сделать это с помощью групп в sed. Чтобы создать новый вывод, вы можете сделать это:

  sed 's/(test="[^"]*)"/1.HELLO"/g' test.txt
  

Чтобы изменить его на месте, вы можете использовать -i переключатель:

  sed -i 's/(test="[^"]*)"/1.HELLO"/g' test.txt
  

Объяснение:

  • () это группа. Вы можете ссылаться на него с 1 помощью . В sed мы должны избегать круглых скобок: ()
  • [^"]* соответствует всему, что не является кавычкой. Таким образом, совпадение остановится перед цитатой
  • При замене вам нужно добавить цитату вручную, поскольку она находится за пределами группы. Таким образом, вы можете поместить материал перед цитатой.

Ответ №2:

Попробуйте это:

Вот как выглядит ваш файл.

 bash > cat a.txt
<test="123">
<test="456">
<test="789">
  

Ваш текст передается в SED

 bash > cat a.txt |sed 's/">/.HELLO">/g'
<test="123.HELLO">
<test="456.HELLO">
<test="789.HELLO">
bash >
  

Дайте мне знать, сработало ли это для вас.

Ответ №3:

 awk 'sub("[0-9] ","amp;.HELLO")' file
  

Ответ №4:

Вы можете выполнить это с помощью sed напрямую. Вырезать не должно быть необходимости:

 grep "test=" test.txt | sed 's/"(.*)"/"1.HELLO"/'
  

Комментарии:

1. grep тоже не нужен, а также -o option не следует использовать в этом случае .. и вы могли бы добавить пример имени файла в команду grep…

2. Хороший звонок, отредактировал мой ответ. Я оставил grep включенным, на случай, если в файле есть посторонние строки, которые OA хочет исключить. Конечно, это можно было бы сделать с помощью sed напрямую, но это кажется более упрощенным.

3. теперь все в порядке 🙂 sed -n '/test=/ s/"(.*)"/"1.HELLO"/p' test.txt тоже просто, но я понимаю вашу точку зрения 🙂