Estoy usando sed en Unix para reemplazar texto con caracteres especiales en un archivo. Lo busco en Google y encuentro el siguiente comando.
sed 's/from/to/g' file.txt
aquí 'desde' es el texto original que se reemplaza, 'hasta' es el texto reemplazado
Estoy intentando aplicar esto a un archivo con texto largo con caracteres especiales, es decir, reemplazando "/D/dec/prog/g++.exe -Wall --std=c++0x" (sin comillas) por "SYSTEM_PATH/BIN" , intento lo siguiente, pero no funciona
sed 's//D/dec/prog/g++.exe -Wall --std=c++0x/SYSTEM_PATH/BIN/g' file.txt
pero aparece el error "sed: -e expresión n.º 1, carácter 10: opción desconocida para `s'".
Soy principiante en Unix, pero por alguna razón necesito iniciar sesión de forma remota en un servidor Unix para manejar algún archivo. Quiero saber
1) ¿Cómo puedo definir la cadena desde y hasta en una variable, algo como FROMSTR = '/D/dec/prog/g++.exe -Wall --std=c++0x' TOSTR = 'SYSTEM_PATH/BIN'
entonces puedo llamar al sed como sed 's/$FROMSTR/$TO/g' file.txt
pero parece que el sed no sabe cómo interpretar eso como variable
2) después de reemplazar el texto por sed, no escribe el resultado en el archivo original. ¿Cómo hacer que funcione?
Respuesta1
El comando sustituto nonecesidadpara utilizarlo /
como delimitador.
sed 's!/D/dec/prog/g++.exe -Wall --std=c++0x!SYSTEM_PATH/BIN!g' file.txt
Respuesta2
Siguiendo las instrucciones de la pregunta: Primero configurando lo que tienes y con qué será reemplazado:
(base) localhost:~ # FROMSTR='/D/dec/prog/g++.exe -Wall --std=c++0x'
(base) localhost:~ # echo $FROMSTR
/D/dec/prog/g++.exe -Wall --std=c++0x
(base) localhost:~ # TOSTR='SYSTEM_PATH/BIN'
(base) localhost:~ # echo $TOSTR
SYSTEM_PATH/BIN
Luego creó un archivo para ejecutar el sed.
(base) localhost:~ # cat > testSED
1/D/dec/prog/g++.exe -Wall --std=c++0x1
2/D/dec/prog/g++.exe -Wall --std=c++0x2/D/dec/prog/g++.exe -Wall --std=c++0x2
3/D/dec/prog/g++.exe -Wall --std=c++0x3
Y luego ejecutamos sed llamando a las variables, pero para la primera necesitamos usar echo:
(base) localhost:~ # sed -e "s|`echo $FROMSTR`|$TOSTR|" testSED
1SYSTEM_PATH/BIN1
2SYSTEM_PATH/BIN2/D/dec/prog/g++.exe -Wall --std=c++0x2
3SYSTEM_PATH/BIN3
(base) localhost:~ # sed -e "s|$FROMSTR|$TOSTR|g" testSED
1SYSTEM_PATH/BIN1
2SYSTEM_PATH/BIN2SYSTEM_PATH/BIN2
3SYSTEM_PATH/BIN3
Algunas cosas para que esto funcione:
- Reemplaza el separador sed de / que es a lo que estamos acostumbrados, con |, o algo que no estés usando en ninguna de las dos variables.
- Si utiliza comillas simples ', las variables se leerán como su nombre y no como su contenido. $TOSTR será $TOSTR y no SYSTEM_PATH/BIN.
- Utilice comillas dobles para poder interpretar las variables.
Si desea que sed reescriba el archivo con el reemplazo realizado, entonces debe agregar -i a las opciones de sed, pero lo que se sugiere es redirigir la salida con > a un nuevo archivo.
(base) localhost:~ # sed "s|$FROMSTR|$TOSTR|g" testSED > testSEDdone
(base) localhost:~ # cat testSEDdone
1SYSTEM_PATH/BIN1
2SYSTEM_PATH/BIN2SYSTEM_PATH/BIN2
3SYSTEM_PATH/BIN3
(base) localhost:~ # cat testSED
1/D/dec/prog/g++.exe -Wall --std=c++0x1
2/D/dec/prog/g++.exe -Wall --std=c++0x2/D/dec/prog/g++.exe -Wall --std=c++0x2
3/D/dec/prog/g++.exe -Wall --std=c++0x3
(base) localhost:~ # sed -i "s|$FROMSTR|$TOSTR|g" testSED
(base) localhost:~ # cat testSED
1SYSTEM_PATH/BIN1
2SYSTEM_PATH/BIN2SYSTEM_PATH/BIN2
3SYSTEM_PATH/BIN3