Substituir padrões que podem se estender por duas linhas

1

Estou tentando entender como a opção N funciona em um editor Sed. Meu objetivo é alterar "Administrador do sistema" para "Usuário da área de trabalho" no "arquivo01" , enquanto a linha de frenagem e até a última linha . Sed não alcançará a última linha porque não haveria uma próxima linha. Outra modificação é necessária, adicionando por exemplo:

sed 's/System Administrator/Desktop User/' , mas isso e:

sed 'System\nAdministrator/Desktop\nUser/' alterna de uma maneira inesperada (para mim), de modo que um dos comandos pare de funcionar na última linha ou nas últimas duas linhas. Isso aconteceu usando N entre os dois ou antes de ambos. Eu estou usando o GNU Sed, versão 4.4.

#cat file01
The first meeting of the Linux System
Administrator's group will be held on Tuesday.
Another line
And here we have: System Administrator's Group as well.
1.System Administrator's group.
2.System Administrators Group.
3.System Administrators Group.
The first meeting of the Linux System
Administrator's group will be held on Tuesday.
System Administrators Group.

Caso 1 , ambos os comandos após N

# sed '
>N
>s/System\nAdministrator/Desktop\nUser/
>s/System Administrator/Desktop User/
> ' file01
The first meeting of the Linux Desktop
User's group will be held on Tuesday.
Another line
And here we have: Desktop User's Group as well.
1.Desktop User's group.
2.System Administrators Group.
3.Desktop Users Group.
The first meeting of the Linux System
Administrator's group will be held on Tuesday.
Desktop Users Group.

Caso 2 , sed 's/System Administrator/Desktop User/' antes de N .

# sed '
> s/System Adminitrator/Desktop User/
> N
> s/System\nAdministrator/Desktop\nUser/
> ' file01
The first meeting of the Linux Desktop
User's group will be held on Tuesday.
Another line
And here we have: System Administrator's Group as well.
1.Desktop User's group.
2.System Administrators Group.
3.Desktop Users Group.
The first meeting of the Linux System
Administrator's group will be held on Tuesday.
System Administrators Group.

Isso pareceu estranho para mim e não consegui descobrir o que estava errado. [Editar]: mais detalhes.

Estou procurando substituir "Administrador do Sistema" por "Usuário da Área de Trabalho" . Além disso, se uma linha termina com "Sistema" e a próxima linha começa com "Administrador", eu os teria substituído de acordo com "Desktop" e "Usuário". Tudo isso foi retirado de um livro, mas a saída não correspondia ao que o livro estava dizendo. Acabei não sabendo o que deu errado. O único mundo que encontrei para descrever o meu problema foi a precedência, peço desculpas, parece que eu estava errado.

    
por pigeon 24.02.2018 / 08:54

2 respostas

2

Isso realmente não tem nada a ver com precedência (que geralmente é algo relacionado a operadores), mas com a ordem na qual os comandos estão sendo emitidos.

Veja o primeiro exemplo na pergunta:

N
s/System\nAdministrator/Desktop\nUser/
s/System Administrator/Desktop User/

Isto irá ler as linhas aos pares e aplicar as duas substituições nelas. Se a segunda linha do par terminar com System (com Administrator no seguinte, terceiro, linha), ele não conseguirá detectar isso. Isso significa que a string, quando estiver sobre uma linha ímpar e outra, não será substituída .

Veja o segundo exemplo na pergunta (com a ortografia corrigida):

s/System Administrator/Desktop User/
N
s/System\nAdministrator/Desktop\nUser/

Isso alterará a string na linha atual, lerá a próxima linha e alterará a string com uma nova linha no meio. Isto não irá alterar as linhas ímpares com uma cópia completa da cadeia (ou linhas ímpares com apenas System ).

Usando o GNU sed :

:top
N
$s/System\(.\)Administrator/DesktopUser/g
b top

Este script faz um loop e lê todas as linhas do arquivo no espaço padrão. Uma vez que ele atinge a última linha de entrada, ele realiza a substituição globalmente, enquanto permite qualquer caractere entre as duas palavras (também pode usar \([ \n]\) ) em vez de \(.\) ).

O resultado será

The first meeting of the Linux Desktop
User's group will be held on Tuesday.
Another line
And here we have: Desktop User's Group as well.
1.Desktop User's group.
2.Desktop Users Group.
3.Desktop Users Group.
The first meeting of the Linux Desktop
User's group will be held on Tuesday.
Desktop Users Group.
    
por 24.02.2018 / 09:29
0

Ao pesquisar padrões que podem ultrapassar duas linhas N é usado junto com P e D - também conhecido como N;P;D cycle , para sempre ter duas linhas no espaço de padrão 1 :

sed '$!N
s/System\nAdministrator/Desktop\nUser/
s/System Administrator/Desktop User/g
P
D' <infile

Observe que a sintaxe s/System\nAdministrator/Desktop\nUser/ é gnu sed . Portably você faria

s/System\nAdministrator/Desktop\
User/

1: começa com as linhas 1-2, depois do P; D processa as linhas 2-3, depois as linhas 3-4 e assim por diante ...

    
por 24.02.2018 / 14:28

Tags