Замена определенного шаблона пробела в sed новой строкой, если у него нет предшествующего двоеточия? - PullRequest
0 голосов
/ 16 ноября 2018

Я пытаюсь проанализировать следующую строку, используя sed для замены пробела на новую строку, только если пробел не предшествует двоеточию.

Например, я использую следующий ввод для обработки:

label1: output label2: output2 label3: "output3" label4: output4 { label5: output5 label6: output6 } label7: output7 { { { label8: output8 } label9: output9 } } label10: output10

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

label1: output
label2: output2
label3: "output3"
label4: output4
{
label5: output5
label6: output6
}
label7: output7
{
{
{
label8: output8
label9: output9
}
}
label10: output10

Когда я пытаюсь использовать следующее регулярное выражение в cat file | sed 's/[^:A-Za-z0-9\"] /%/g' | tr '%' '\n', это приводит к выводу ниже, который близок, но не достигает цели:

    label1: output label2: output2 label3: "output3" label4: output4
    label5: output5 label6: output6
    label7: output7


    label8: output8
    label9: output9

    label10: output10

Я также пробовал это cat file | sed 's/[^:A-Za-z0-9\"] /%/g' | tr '%' '\n', и это приводит к

label1: outpu
label2: output
label3: "output3
label4: output

label5: output
label6: output

label7: output



label8: output

label9: output


label10: output10

Похоже, что регулярное выражение также включает замену любого другого символа, который не является :, новой строкой.

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Это может сработать для вас (GNU sed):

sed 'G;:a;s/\([^: ]\) \(.*\(.\)\)/\1\3\2/;ta;s/.$//' file

Добавить новую строку к текущей строке с помощью команды G, которая по умолчанию добавляет пустой пробел в пространство образца.Используя сопоставление с образцом и обратные ссылки, выполните итерацию по всей текущей строке, заменив символ пробела / не двоеточия, а затем пробел добавленной новой строкой.Если дальнейших совпадений больше нет, удалите артефакт новой строки и напечатайте строку.

Это же решение можно просмотреть проще, используя параметр -r (только для GNU sed), который удаляет многие обратные слеши:

sed  -r 'G;:a;s/([^: ]) (.*(.))/\1\3\2/;ta;s/.$//' file

Также, как указано, оптимальным решением будет:

sed  's/\([^: ]\) /\1\n/g' file
0 голосов
/ 16 ноября 2018

Это должно сделать это:

sed -E 's/([^:]) /\1\n/g' file

Вывод:

label1: output
label2: output2
label3: "output3"
label4: output4
{
label5: output5
label6: output6
}
label7: output7
{
{
{
label8: output8
}
label9: output9
}
}
label10: output10

Ура!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...