2011-04-21 8 views
5

me gustaría saber cómo puedo sustituir a la primera ocurrencia del patrón buscado en todo el ejemplo file.For,primer reemplazo de una cadena en un archivo usando sed

import java.io.File; 
import java.io.File; 

debe sustituirse por

import java.io.IOException; 
import java.io.File; 

¿Cómo logro esto usando sed? Gracias

+0

posible duplicado de (http://stackoverflow.com/questions/148451/how -to-use-sed-to-replace-only-the-first-occurrence-in-a-file) –

Respuesta

0

puede utilizar un script de shell (Bash)

#!/bin/bash 

declare -i toggle=0 
while read -r line 
do 
     case "$line" in 
      *import*java.io.File*) 
      if [ $toggle -eq 1 ];then 
       echo "$line" 
       continue 
      fi 
      echo "import java.io.Exception"; 
      toggle=1 
      continue 
      ;; 
     esac 
     echo "$line" 
done < file 

Salida de ejemplo

$> more file 
import java.util.Scanner; 
import java.io.File; 
import java.io.File; 

$> bash search_replace.sh 
import java.util.Scanner; 
import java.io.Exception 
import java.io.File; 

O puede sorber todo el archivo en la memoria y hacer un cambio una vez

data=$(<file) 
echo "${data/import java.io.File;/import java.io.IOException}" 
0

Simplemente hágalo en la línea de comandos de la siguiente manera:

cat text.txt | 
awk '/File/{ 
    if (count < 1){ gsub("File","IOException")} 
    count++ 
    print 
    }' 
2

No hay necesidad de escribir grandes secuencias de comandos largas cuando solo se necesita una sustitución para hacer todo el trabajo en una línea. Solo tiene que elegir la herramienta eléctrica correcta para el trabajo.

Aquí hay una Perl de una sola línea:

% cat -n /tmp/f 
    1 import java.lang.Character; 
    2 import java.io.File; 
    3 import java.io.File; 
    4 import java.util.Pattern; 

% perl -pe 's//IoException/ if m?import java\.io\.\KFile?' /tmp/f 
import java.lang.Character; 
import java.io.IoException; 
import java.io.File; 
import java.util.Pattern; 

Y si quiere hacerlo con una edición del archivo, sólo tiene que añadir -i.bak:

% perl -i.bak -pe 's//IoException/ if m?import java\.io\.\KFile?' /tmp/f 

% head /tmp/f{,.bak} 
==> /tmp/f <== 
import java.lang.Character; 
import java.io.IoException; 
import java.io.File; 
import java.util.Pattern; 

==> /tmp/f.bak <== 
import java.lang.Character; 
import java.io.File; 
import java.io.File; 
import java.util.Pattern; 

La razón que funciona es porque cuando le da al operador m// un delimitador ??, tiene un estado incorporado para recordar coincidir con la primera vez solamente.

Luego, en el sustituto, el patrón vacío significa reutilizar el último patrón combinado, por lo que no tiene que volver a escribirlo y arriesgarse a que los dos divergentes.

Por último, el \K en el patrón incumple el partido, "manteniendo" las cosas a la izquierda, para que no se quede engullido por el sustituto.

2
cat file | sed -e ':l 
    0,/my_search_str/ { 
    /my_search_str/! { 
      N; 
      b l 
      } 
    s/my_search_str/replace_this/g 
    :t 
    N 
    b t  
    } 
    ' 

esto funciona para mí: archivo: (antes)

hello1 
my_search_str 
hello2 
mysearch_str 
hello3 

archivo: (después)

hello1 
replace_this 
hello2 
mysearch_str 
hello3 
1

Lo que quiero hacer es añadir todas las líneas en una gran línea y reemplazar el contenido.

$ cat f 
import java.io.File; 
import java.io.File; 
$ sed -n 'N 
    ${ 
    s/import java.io.File;/import java.io.IOException/ 
    p 
    }' f 
import java.io.IOException 
import java.io.File; 

Cómo funciona: primero, suprimir la impresión de línea, que es el comportamiento por defecto, pasando la opción -n de sed.

Luego vienen los comandos sed.El primero es el comando N: agrega una nueva línea y la siguiente línea de la secuencia a la actual, manteniéndose luego en el espacio del patrón. Esto cambiará la línea actual a la siguiente, y luego se agregará la siguiente línea ... hasta el final del archivo.

Al final del archivo y luego del comando N que se ejecutará también en la última línea, el espacio del patrón contendrá todas las líneas. Luego, al final del archivo (que se especifica por la dirección de $) que basta con sustituir la línea deseada con:

s/import java.io.File;/import java.io.IOException/ 

Desde el comando s/// hace sólo un reemplazo por iteración en el espacio de patrones por defecto, solo reemplazará la primera línea. Ahora el espacio del patrón tiene la línea reemplazada, pero no se imprimirá ya que usamos la opción -n. Entonces, necesitamos imprimirlo con el comando p. Una vez que ejecutaremos dos operaciones al final del archivo, lo direccionamos con $ y colocamos las operaciones entre corchetes ({}).

Ahí, presentamos los comandos sed en más de una línea para mayor claridad. Podemos usarlos todos en una línea; simplemente separarlos por punto y coma: [? Cómo usar sed para reemplazar sólo la primera aparición en un archivo]

$ sed -n 'N;${s/import java.io.File;/import java.io.IOException/;p;}' f 
import java.io.IOException 
import java.io.File; 

HTH

Cuestiones relacionadas