Все, что вам нужно:
$ echo 'Hello (world)' | sed 's/(/(40\n/g; s/)/(41)/g; s/\n/)/g'
Hello (40)world(41)
выше безопасен, потому что \n
не может присутствовать на входе, так как СЭД читает по одной строке за раз. С некоторыми семенами вам может потребоваться использовать обратную косую черту, за которой следует буквальная новая строка или $'\n'
, а не только \n
.
Учитывая the answer you posted, хотя, это может быть то, что вы действительно хотите (использует GNU AWK для ord(), мульти-символ RS
и RT
):
$ cat tst.awk
@load "ordchr"
BEGIN { RS = "[][(){}]"; ORS="" }
{ print $0 (RT=="" ? "" : "(" ord(RT) ")") }
$ echo 'Hello (world) foo [bar] other {stuff} etc.' | awk -f tst.awk
Hello (40)world(41) foo (91)bar(93) other (123)stuff(125) etc.
Если у вас есть старый Gawk, который не поддерживает @load
, чем получить новый, но если это невозможно по каким-то причинам, то просто создать массив значений, например:
$ cat tst.awk
BEGIN {
RS = "[][(){}]"
ORS = ""
for (i=0;i<=255;i++) {
char = sprintf("%c",i)
map[char] = "(" i ")"
}
}
{ print $0 (RT=="" ? "" : map[RT]) }
$ echo 'Hello (world) foo [bar] other {stuff} etc.' | awk -f tst.awk
Hello (40)world(41) foo (91)bar(93) other (123)stuff(125) etc.
EDIT: выбор времени Данные
Учитывая файл, который имеет следующие 10 строк:
$ head -10 file1m
When (chapman) billies leave [the] street, And drouthy {neibors}, neibors, meet;
As market days are wearing late, And folk begin to [tak] the gate,
While (we) sit bousing {at} the nappy, An' getting [fou] and unco happy,
We think na on the [lang] Scots (miles), The mosses, {waters}, slaps and stiles,
That lie between us and our hame, Where sits our sulky, sullen dame,
Gathering her [brows] like gathering storm, (Nursing) her wrath to keep it warm.
This truth fand honest Tam o' Shanter,
As he frae Ayr ae night did canter:
(Auld Ayr, wham ne'er a town surpasses,
For honest men and bonie lasses).
повторяющимися в общей сложности 1 млн линий, 10,5 миллиона символов, 60,4 миллионов байт:
$ wc file1m
1000000 10500000 60400000 file1m
3-й перспективе статистика времени для сценария sed и оба сценария awk выше:
$ time sed 's/(/(40\n/g; s/)/(41)/g; s/\n/)/g; s/\[/(91)/g; s/\]/(93)/g; s/{/(123)/g; s/}/(125)/g;' file1m > sed.out
real 0m7.488s
user 0m7.378s
sys 0m0.093s
$ cat function.awk
@load "ordchr"
BEGIN { RS = "[][(){}]"; ORS="" }
{ print $0 (RT=="" ? "" : "(" ord(RT) ")") }
$ time awk -f function.awk file1m > awk_function.out
real 0m7.426s
user 0m7.269s
sys 0m0.155s
$ cat array.awk
BEGIN {
RS = "[][(){}]"
ORS = ""
for (i=0;i<=255;i++) {
char = sprintf("%c",i)
map[char] = "(" i ")"
}
}
{ print $0 (RT=="" ? "" : map[RT]) }
$ time awk -f array.awk file1m > awk_array.out
real 0m4.758s
user 0m4.648s
sys 0m0.092s
Я проверил, что все 3 скрипты производят один и тот же, успешно Измененный вывод:
$ head -10 sed.out
When (40)chapman(41) billies leave (91)the(93) street, And drouthy (123)neibors(125), neibors, meet;
As market days are wearing late, And folk begin to (91)tak(93) the gate,
While (40)we(41) sit bousing (123)at(125) the nappy, An' getting (91)fou(93) and unco happy,
We think na on the (91)lang(93) Scots (40)miles(41), The mosses, (123)waters(125), slaps and stiles,
That lie between us and our hame, Where sits our sulky, sullen dame,
Gathering her (91)brows(93) like gathering storm, (40)Nursing(41) her wrath to keep it warm.
This truth fand honest Tam o' Shanter,
As he frae Ayr ae night did canter:
(40)Auld Ayr, wham ne'er a town surpasses,
For honest men and bonie lasses(41).
$ wc sed.out
1000000 10500000 68800000 sed.out
$ diff sed.out awk_function.out
$ diff sed.out awk_array.out
$
заменить на '[40]', то есть окончательный проход, который заменяет все '[' с '(', и т.д. Удачи. – shellter
Как смущающе, почему я не подумал об этом ?! Я убегаю [], так что это хорошее решение.Изменить: нет, подождите, пока это не сработает, потому что [] экранированы ... –
@shellter: Вы можете рассмотреть вопрос об отправке ответа на этот вопрос: D – sjsam