Sed palavra inteira ao substituir letras simples, com BSD sed?

1

Acho que encontrei algumas soluções GNU, mas preciso de BSD sed solutions.

O que eu quero fazer é substituir a palavra inteira de uma só vez. Se a palavra é "clayii", e meu código é sed 's/c/k/g;s/l/i/g;s/a/e/g;s/y/i/g;s/k/o/g' , eu quero produzir "kieii", mas produz "oieiii" por razões óbvias. Na última seção, ele procura k e o encontra no começo, mas se ele pesquisou a palavra inteira, nunca faria isso.

Obviamente, "clayii" será diferente o tempo todo, eu quero substituir letras individuais, mas não começar desde o começo, se já tiver substituído o primeiro n e depois encontrar no começo ele não deve recomeçar. Então, basicamente, ignore o que já foi substituído, se isso for detectável.

Existe uma solução para isso?

    
por DisplayName 02.12.2015 / 00:48

3 respostas

1

Talvez use y// (comando interno do sed) insteaad de s/// :

$ echo clayii | sed -e '/clayii/ y/clayk/kieio/'
kieiii

Observe que o comando y// ainda se aplica a toda a linha, não apenas à palavra correspondente.

    
por 02.12.2015 / 00:59
0

Com o BSD sed, você pode usar:

sed "s/[[:<:]]clayii[[:>:]]/kieii/g" /path/to/file
    
por 02.12.2015 / 00:58
0

você pode passar por cima dele:

echo  here is a pat and a tern and a pattern     |
sed  -e'1{H;x;s/\(.\).*/patternreplace/;x;}' \
-eG  -e'/\(.*\)\(.*\n\)\(\n\)\n/!{P;d;}'       \
     -e's///;t-'                             \
-e:- -e's/\(\n\)\(.\)\(.*\n\)\(.\)//;t-'   \
     -e's/\n//;P;d'
here is a pat and a tern and a replace

Isso faz o caractere de substituição por caractere progredindo da esquerda para a direita. Ele desloca o primeiro delimitador para a direita do caractere substituído para cada substituição. Você pode ver o que quero dizer se colocar um comando l ook logo antes da substituição do loop t ested após -e:- :

here is a pat and a tern and a \npattern\nreplace$
here is a pat and a tern and a r\nattern\neplace$
here is a pat and a tern and a re\nttern\nplace$
here is a pat and a tern and a rep\ntern\nlace$
here is a pat and a tern and a repl\nern\nace$
here is a pat and a tern and a repla\nrn\nce$
here is a pat and a tern and a replac\nn\ne$
here is a pat and a tern and a replace\n\n$
here is a pat and a tern and a replace

Se você realmente está procurando por uma espécie de tradução, pode fazer isso também. Eu escrevi isso antes como uma resposta para outra pergunta:

It looks doable - you just have to sort of shift-in/shift-out:

echo can ccccc ccccccccclayii sed clay ignore \
     every cclayii thing but the matching word\
     - cclayiicclayii |
sed     -e'y/ /\n/' \
-eh     -e's/\(cclayii\)*/ & /g;x;s// /g;s/^/ /' \
-ex     -e's//./;s/\([^ ]* *\)\{2\}/ /g;s/^/ /'  \
        -e'y/clayk/kieio/;G;t$' -e:$  \
        -e'/^ \n /{s///;y/ \n/\n /;}' \
-et     -e's/^ *\([^ ]*\) \(.* \n [^ ]*\) //;t$'

can ccccc ccccccckkieiii sed clay ignore every kkieiii thing but the matching word - kkieiiikkieiii

...it isn't easy, though.

Essa volta um pouco também, mas não tanto.

As is true of most complicated problems, though, it is way easier if you use two seds:

echo can ccccc ccccccccclayii sed clay ignore \
     every cclayii thing but the matching word\
     - cclayiicclayii |
sed -e's/\(cclayii\)*/\n&\n /g;G;s/^/ /'|
sed -e'/^ /!y/clayk/kieio/;/./{H;d;}' \
    -e'x;s/\n \{0,1\}//g'

can ccccc ccccccckkieiii sed clay ignore every kkieiii thing but the matching word - kkieiiikkieiii

Com um BSD sed , você desejará usar uma nova linha literal no lugar do n nos \n escapes na substituição à direita do primeiro sed lá.

    
por 02.12.2015 / 17:24

Tags