У меня есть файл с текстом, в котором некоторые важные элементы отмечены начальной и закрывающей фигурными скобками, например:

Once upon a {time}, there lived a rabbit.
The {rabbit lived} in a small house.
One day, the {rabbit visited }the {mountains}.
In the mountains, he {found} a tree with 10{,000} branches.

Мне нужно заменить все элементы в форме {x} на {x::x}, например:

Once upon a {time::time}, there lived a rabbit.
The {rabbit lived::rabbit lived} in a small house.
One day, the {rabbit visited ::rabbit visited }the {mountains::mountains}.
In the mountains, he {found::found} a tree with 10{,000::,000} branches.
  • Каждому открытию { соответствует } в той же строке.
  • Фигурные скобки никогда не разделяются на линии.
  • Фигурные скобки никогда не бывают вложенными.
  • Между { и } могут быть любые символы.

Я пробовал несколько подходов с sed, но ничего не помогло, например:

sed 's/{(.*)}/{&::&}/g' file.txt

Как заменить все элементы в фигурных скобках, например {some word} с шаблоном {some word::some word}?

0
Village 20 Май 2014 в 08:29

4 ответа

Лучший ответ

Будет проще, если вы сможете использовать perl:

$ perl -ple 's/{(.*?)}/{$1::$1}/g' file
Once upon a {time::time}, there lived a rabbit.
The {rabbit lived::rabbit lived} in a small house.
One day, the {rabbit visited ::rabbit visited }the {mountains::mountains}.
In the mountains, he {found::found} a tree with 10{,000::,000} branches.

Он сопоставляет все элементы внутри фигурных скобок {...} не жадные , а затем заменяет их желаемой строкой {$1::$1}.

2
cuonglm 20 Май 2014 в 04:37

Вот исправление

sed 's/{\([^}]*\)}/{\1::\1}/g' file

Once upon a {time::time}, there lived a rabbit.
The {rabbit lived::rabbit lived} in a small house.
One day, the {rabbit visited ::rabbit visited }the {mountains::mountains}.
In the mountains, he {found::found} a tree with 10{,000::,000} branches.

Объяснение

  • [^}]* соответствуют не - } символам
  • \(...\) захватит символы, указанные внутри скобок, а \ 1 будет использоваться для ссылки на первое совпадение, это часть регулярного выражения.
4
BMW 20 Май 2014 в 04:32

Вы должны использовать

sed 's/\([^{]*{\)\([^}]*\)\(}.*\)/\1\2::\2\3/'

Не испытано

1
Jonathan Wheeler 20 Май 2014 в 04:34

awk вариант:

$ awk 'BEGIN{ORS=""} NR%2==0{$0="{"$0"::"$0"}"} 1' RS='[{}]' file.txt

Once upon a {time::time}, there lived a rabbit.
The {rabbit lived::rabbit lived} in a small house.
One day, the {rabbit visited ::rabbit visited }the {mountains::mountains}.
In the mountains, he {found::found} a tree with 10{,000::,000} branches.
1
anishsane 20 Май 2014 в 05:57