Если ваш ввод не содержит <
, >
или +
символов, вы можете сделать:
sed '
s/[[:alnum:]]\{1,\}/<&>/g;:1
s/\(<\([^>]*\)>.*\)<\2>/\1+\2+/;t1
s/[<>]//g'
Если это возможно, вы всегда можете избежать их:
sed '
s/:/::/g;s/</:{/g;s/>/:}/g
s/[[:alnum:]]\{1,\}/<&>/g;:1
s/\(<\([^>]*\)>.*\)<\2>/\1+\2+/;t1
s/[<>]//g
s/:}/>/g;s/:{/</g;s/::/:/g'
Те, кто предполагают, что вы хотите сделать это независимо на каждой строке. Если Вы хотите сделать это по всему файлу, то сначала нужно загрузить весь файл в память (обратите внимание, что некоторые реализации sed
имеют там ограничения по размеру):
sed '
:2
$!{N;b2
}
s/:/::/g;s/</:{/g;s/>/:}/g
s/[[:alnum:]]\{1,\}/<&>/g;:1
s/\(<\([^>]*\)>.*\)<\2>/\1+\2+/;t1
s/[<>]//g
s/:}/>/g;s/:{/</g;s/::/:/g'
Это будет довольно неэффективно и было бы намного проще с perl
:
perl -pe 's/\w+/$seen{$&}++ ? "+$&+" : $&/ge'
На основе строк:
perl -pe 'my %seen;s/\w+/$seen{$&}++ ? "+$&+" : $&/ge'
Сработает ли это для вас?:
$ grep -F -f serverlist.txt alias.txt
alias server1='ssh root@server1.com'
alias server2='ssh root@server2.com'
alias server3='ssh root@server3.com'
Он использует строки из serverlist.txt
в качестве шаблонов для отображения строк формы alias.txt
. В зависимости от имен ваших серверов может потребоваться немного сложнее, чтобы не давать неправильных совпадений, например, если сервер назван просто server
.
Было бы намного безопаснее сначала преобразовать простые имена серверов в шаблоны, соответствующие только левой части определения псевдонима:
$ sed "s/\(.*\)/^alias \1='/" serverlist.txt
^alias server1='
^alias server2='
^alias server3='
Мы можем использовать -f -
для чтения шаблонов из stdin, точно так же, как мы делали это прямо из файла раньше:
$ sed "s/\(.*\)/^alias \1='/" serverlist.txt | grep -f - alias.txt
alias server1='ssh root@server1.com'
alias server2='ssh root@server2.com'
alias server3='ssh root@server3.com'