Estou usando o sed no unix para substituir algum texto por caracteres especiais em um arquivo. Eu pesquisei no Google e encontrei o seguinte comando
sed 's/from/to/g' file.txt
aqui 'de' é o texto original que está sendo substituído, 'para' é o texto de substituição
Estou tentando aplicar isso a um arquivo com texto longo com caracteres especiais, ou seja, substituindo "/D/dec/prog/g++.exe -Wall --std=c++0x" (sem aspas) por "SYSTEM_PATH/BIN" , tento o seguinte, mas não funciona
sed 's//D/dec/prog/g++.exe -Wall --std=c++0x/SYSTEM_PATH/BIN/g' file.txt
mas isso gerou o erro "sed: -e expressão #1, char 10: opção desconhecida para `s'".
Sou iniciante em Unix, mas por algum motivo preciso fazer login remotamente em um servidor Unix para manipular alguns arquivos. Eu quero saber
1) como posso definir a string from e to para uma variável, algo como FROMSTR = '/D/dec/prog/g++.exe -Wall --std=c++0x' TOSTR = 'SYSTEM_PATH/BIN'
então eu posso chamar o sed como sed 's/$FROMSTR/$TO/g' file.txt
mas parece que o sed não sabe como interpretar isso como variável
2) após substituir o texto por sed, ele não grava o resultado no arquivo original. Como fazer dar certo?
Responder1
O comando substituto nãoprecisarpara usar /
como delimitador.
sed 's!/D/dec/prog/g++.exe -Wall --std=c++0x!SYSTEM_PATH/BIN!g' file.txt
Responder2
Seguindo as instruções da pergunta: Primeiro definindo o que você tem e com o que será substituído:
(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
Em seguida, criei um arquivo para executar o 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
E então rodar sed chamando as variáveis, mas para a primeira precisamos 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
Algumas coisas para que isso funcione:
- Substitua o separador sed de / que é o que estamos acostumados, por |, ou algo que você não esteja usando em nenhuma das duas variáveis.
- Se você usar aspas simples ', as variáveis serão lidas como seu nome e não como seu conteúdo. $TOSTR será $TOSTR e não SYSTEM_PATH/BIN.
- Use aspas duplas para poder interpretar as variáveis.
Se você quiser fazer com que o sed reescreva o arquivo com a substituição feita, então você deve adicionar -i às opções do sed, mas o que é sugerido é redirecionar a saída com > para um novo arquivo.
(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