Como substituir m parte de linhas com n parte de linhas?

5

Eu tenho um arquivo "teste" assim:

RewiteEngine On
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.7$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.8$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.9$  [NC]
RewriteCond   %{REMOTE_ADDR}   ^192\.168\.1\.5$  [NC]
</Directory>

Desejo substituir \.1\.7 , \.1\.8 e \.1\.9 por \.1\.10 , por isso, será:

RewiteEngine On
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.10$  [NC]
RewriteCond   %{REMOTE_ADDR}   ^192\.168\.1\.5$  [NC]
</Directory>

pode ser a substituição de m "IPS" por n "IPS". Como posso alcançar isso?

    
por Networker 04.08.2014 / 15:47

4 respostas

4

Uma solução perl :

$ perl -ple 's/\\.1\\.(7|8|9)/\.1\.10/' file | uniq
RewiteEngine On
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.10$  [NC]
RewriteCond   %{REMOTE_ADDR}   ^192\.168\.1\.5$  [NC]
</Directory>

Se você quiser editar no local, pode tentar:

perl -i.bak -nle 'next if $count and /!\^/;s/\\.1\\.(7|8|9)/\.1\.10/ and $count++ if /!\^/;print' file
    
por 04.08.2014 / 15:59
2

Eu consegui fazer isso excluindo todas as linhas e reinserindo-as, mas quero uma solução ideal (porque aqui está excluindo toda a linha e adicionando uma nova linha inteira) e quero adicionar espaços em branco às linhas adicionadas :

excluir:

sed -i '/!^.*$/d' test2

inserir de volta:

 sed -i '/RewiteEngine On/aRewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.10$  [NC]' test2

a saída é:

  RewiteEngine On
RewriteCond   %{REMOTE_ADDR}   !^192.168.1.10$  [NC] # need whites spaces at the begining
  RewriteCond   %{REMOTE_ADDR}   ^192\.168\.1\.5$  [NC]
    
por 04.08.2014 / 15:48
2
sed '/!/d;/\(\^[^5]*\)./{h;s//!0/p;g;}' <<\DATA
RewiteEngine On
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.7$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.8$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.9$  [NC]
RewriteCond   %{REMOTE_ADDR}   ^192\.168\.1\.5$  [NC]
</Directory>
DATA

OUTPUT

RewiteEngine On
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.10$  [NC]
RewriteCond   %{REMOTE_ADDR}   ^192\.168\.1\.5$  [NC]
</Directory>

Então, isso depende do s/ubsti/tution/ correspondente ao último endereço - o que ele fará. Quando um /address/ está vazio como s// ou // , o endereço anterior está implícito. Exclui todas as linhas /!/ que contêm um estrondo, depois endereça em uma linha com ^ e coloca isso em espaço de espera. Em seguida, ele o edita, p o reimpre e o substitui novamente com seu valor original ainda em h old space.

Mas se o endereço de correspondência puder corresponder à linha h old e às linhas editadas, você poderá continuar editando-as. Talvez assim:

sed '/!/d;/\(\^[^$]*\.\)[0-9]*/{h;s//!0/p;s//1/p;s//2/p;g;}' <<\DATA
RewiteEngine On
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.7$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.8$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.9$  [NC]
RewriteCond   %{REMOTE_ADDR}   ^192\.168\.1\.5$  [NC]
</Directory>
DATA

OUTPUT

RewiteEngine On
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.10$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.11$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.12$  [NC]
RewriteCond   %{REMOTE_ADDR}   ^192\.168\.1\.5$  [NC]
</Directory>

Honestamente, porém, mais do que isso e você provavelmente quer abordá-lo de forma um pouco diferente. Talvez com printf ?

ips() { printf 's//\1%d/p;' $(seq "$@") ; echo 'g;}' ; }

sed '/!/d;/\(\^[^$]*\.\)[0-9]*/{h;s//!0/p;'"$(ips 11 30)" <<\DATA
RewiteEngine On
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.7$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.8$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.9$  [NC]
RewriteCond   %{REMOTE_ADDR}   ^192\.168\.1\.5$  [NC]
</Directory>
DATA

OUTPUT

RewiteEngine On
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.10$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.11$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.12$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.13$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.14$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.15$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.16$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.17$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.18$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.19$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.20$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.21$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.22$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.23$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.24$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.25$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.26$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.27$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.28$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.29$  [NC]
RewriteCond   %{REMOTE_ADDR}   !^192\.168\.1\.30$  [NC]
RewriteCond   %{REMOTE_ADDR}   ^192\.168\.1\.5$  [NC]
</Directory>
    
por 04.08.2014 / 21:21
2

Uma maneira com gawk :

awk '{gsub(/\.[7-9]\$/,"\.10$")}!a[$0]++' test
    
por 04.08.2014 / 16:46