Por que isso não funciona quando eu o adiciono ao sed atual sendo executado?

1

Eu tenho um arquivo de texto com esta aparência:

(empty) 
str
int
int 

Se eu adicionar este s/^/\</g ao meu atual sed (tornando-o 's/\&/\</g;s/\</\ /g;s/^/\</g' ) esta é a saída.

< ##only this line gets a < 
str
int
int 

Mas se eu fizer uma nova linha e digitar o comando inteiro como sed -i '' 's/^/\</g' *.p* , esta é a saída

< 
<str
<int
<int 

Que diferença faz?

    
por DisplayName 11.12.2015 / 23:45

2 respostas

0

A diferença está relacionada com entrada e saída. No primeiro caso, você está inserindo um \n ewline, sim, mas ainda está operando no mesmo espaço de padrão - e assim a ^ head do espaço padrão permanece onde está, mesmo que contenha novas linhas incorporadas - que você insere para cada ocorrência de < .

Mas, no segundo caso, você está trabalhando com um novo sed e lendo a última saída sed s como entrada - e, portanto, todas as novas linhas que ele injetou contam como linhas de entrada separadas agora, e cada um recebe seu próprio ^ head do espaço padrão.

echo ..... | 
sed 's/./&\
/g;s/^/sed1/' |
sed 's/^/sed2/'
sed2sed1.
sed2.
sed2.
sed2.
sed2.
sed2

A propósito ...

sed 's/&/</g;s/</\
/g'

... provavelmente é mais facilmente escrito ...

sed 'y/&</\n\n/'

... mas se você quiser apenas colocar uma nova linha por trás de cada [&<] e substituir cada & por < , poderá fazer:

sed 's/[&<]/<\
/g'

... mas sua saída não corresponde à sua entrada ...

    
por 12.12.2015 / 18:10
0
sed 'expression;expression' 

é o mesmo que

sed -e 'expression' -e 'expression'

que, em alguns casos simples , é o mesmo que

sed -e 'expression' | sed -e 'expression'

No seu caso (pelo que vejo), você está tentando alterar todos os & para < . Então, todo < em novas linhas e, finalmente, você adiciona < ao início das linhas:

s/\&/\</g;s/\</\
/g;s/^/\</g

Com a entrada fornecida, esse script sed fará o seguinte com BSD sed :

$ sed -f script.sed file
<
<

<

<

Ou com o GNU sed :

$ gsed -f script.sed file
<
<
str
<
int
<
int

Por que isso acontece?

  1. Antes de mais nada, não há & no arquivo (o \ na frente de & também pode ser descartado), então a primeira expressão é um não operacional.
  2. A segunda expressão corresponde a \< , que é um limite de (início de) palavra. Para ser honesto, estou um pouco perplexo com a remoção do texto pelo BSD sed (verei se isso é um bug no OpenBSD sed ). Portanto, isso insere uma nova linha no início de cada palavra do arquivo de exemplo.
  3. A terceira expressão, ainda operando na mesma linha de entrada (agora modificada), insere um < no início da linha.

Em contraste, a expressão única s/^/\</g (na qual o \ na frente de < e o modificador g não é necessário) apenas insere um < no início de cada linha .

Follow-up: Foi confirmado que havia um bug na implementação de sed no OpenBSD 6.1-stable em relação à inclusão de uma string em uma linha que começa com uma nova linha inserida. Um patch foi enviado.

    
por 24.09.2017 / 15:24

Tags