Как добавить пробел до и после определенных символов с помощью sed или awk?

#bash #shell #awk #sed

#bash #оболочка #awk #sed

Вопрос:

Я знаю, что могу добавить пробел после или перед символом, используя

 sed -i 's/char/char /g' fname.txt
 

Однако мне нужна помощь в добавлении пробела до и после этих символов «[]<>»‘

например,

 nie[breath]hi
hi </langenglish>'tjie
 

превратилось бы в

 nie [breath] hi
hi </langenglish> 'tjie
 

ПРИМЕЧАНИЕ: мне нужен один пробел после <>[] , потому что, используя первый код, я бы, по сути, получил два пробела.

Пожалуйста, дайте мне знать, как я мог бы выполнить эту задачу.

Ответ №1:

Из вашего примера кажется, что вы неправильно указываете свою проблему, и на самом деле вам нужен пробел перед и после каждой [...] <...> строки or, а не перед и после каждого [ символа , ] , < , или > . Если это правильно, то используйте любой sed, который позволяет n представлять новую строку в регулярном выражении и заменяющем тексте (например, GNU sed):

 $ sed 's/ /n/g; s/[[^]]*]/ amp; /g; s/<[^>]*>/ amp; /g; s/ *n */ /g' file
nie [breath] hi
hi </langenglish> 'tjie
 

или с любым awk:

 $ awk '{gsub(/ /,"n"); gsub(/[[^]]*]/," amp; "); gsub(/<[^>]*>/," amp; "); gsub(/ *n */," ")} 1' file
nie [breath] hi
hi </langenglish> 'tjie
 

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

 $ echo 'head[foo<bar]tail' | awk '{gsub(/ /,"n"); gsub(/[[^]]*]/," amp; "); gsub(/<[^>]*>/," amp; "); gsub(/ *n */," ")} 1'
head [foo<bar] tail

$ echo 'head<foo<bar>tail' | awk '{gsub(/ /,"n"); gsub(/[[^]]*]/," amp; "); gsub(/<[^>]*>/," amp; "); gsub(/ *n */," ")} 1'
head <foo<bar> tail

$ echo 'head<foo[bar>tail' | awk '{gsub(/ /,"n"); gsub(/[[^]]*]/," amp; "); gsub(/<[^>]*>/," amp; "); gsub(/ *n */," ")} 1'
head <foo[bar> tail

$ echo 'head<foo]bar>tail' | awk '{gsub(/ /,"n"); gsub(/[[^]]*]/," amp; "); gsub(/<[^>]*>/," amp; "); gsub(/ *n */," ")} 1'
head <foo]bar> tail

$ echo 'head<foo[bar]tail' | awk '{gsub(/ /,"n"); gsub(/[[^]]*]/," amp; "); gsub(/<[^>]*>/," amp; "); gsub(/ *n */," ")} 1'
head<foo [bar] tail
 

Ответ №2:

Не могли бы вы попробовать следующее. Написано только в соответствии с показанными примерами. Это добавит пробелы до [ , а < затем добавит пробелы после > и ] . Согласно показанным примерам.

 awk '{gsub(/[|</," amp;");gsub(/]|>/,"amp; ")} 1' Input_file
 

Объяснение: просто глобально подставляя [ и > с пробелами перед их значениями в first gsub . Затем выполните вторую глобальную замену, чтобы добавить пробелы после > и ] .

Ответ №3:

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

 sed 's/[[:space:]]*([]>])[[:space:]]*/1 /g;s/[[:space:]]*([[<])[[:space:]]*/ 1/g' file > newfile
 

Смотрите онлайн-демонстрацию:

 s="nie[breath]hi
hi </langenglish>'tjie"
sed 's/[[:space:]]*([]>])[[:space:]]*/1 /g;s/[[:space:]]*([[<])[[:space:]]*/ 1/g' <<< "$s"
 

Вывод:

 nie [breath] hi
hi </langenglish> 'tjie
 

Подробные сведения:

  • s/[[:space:]]*([]>])[[:space:]]*/1 /g — «нормализует» пробелы до ] и > символы, удаляя все пробелы до и сохраняя один после
  • s/[[:space:]]*([[<])[[:space:]]*/ 1/g — «нормализует» пробелы до [ и < символы, удаляя все пробелы после и сохраняя один перед