Substituir uma barra invertida por sed

3

Estou tentando criar um script que substitua todas as ocorrências de C:\ em dois tipos diferentes de arquivo por /root .

Minha arborescência parece:

- Batch
  - Place of the script
- Conf
  - Appli1
    - File1.xml
    - File2.xml
    - ...
  - Appli2
    - File1.xml
    - File2.xml
    - ...
  - ...
- Info
  - File1.conf
  - File2.conf
  - ...

Meu script é assim em /Batch :

#/bin/bash
find ../ -name "*.xml" -o name "*.conf" -print | xargs sed -i 's C:\ /root/ g'

Mas, eu tenho um erro no sed part , que diz que em character 14: command 's' unfinished

Por que isso acontece?

    
por xhaltar 20.08.2014 / 10:31

2 respostas

4

Onde você usa:

sed -i 's C:\ /root/ g'

você está usando o s command com um caractere de espaço separando as diferentes partes do comando, o que é incomum, mas completamente válido. Quando você precede seu caractere separador com uma barra invertida, ele não é tratado como um separador, mas como parte do argumento em si.

O problema que você tem aqui é que a barra invertida em C:\ está escapando do espaço no meio, então s nunca encontra o fim da substituição (que agora é g ) e reclama que o comando está inacabado como você viu.

No mínimo, você precisa escapar da própria barra invertida com outra barra invertida:

sed -i 's C:\ /root/ g'

Isso funcionará, embora a substituição dos espaços por outro caractere possa ser mais clara.

Quanto ao uso de xargs e subdiretórios - xargs não é necessário aqui, e O find pode fazer isso, incluindo o manuseio de arquivos em subdiretórios, por conta própria. Use:

find ../ \( -name "*.xml" -o -name "*.conf" \) -exec sed -i -e 's|C:\|/root/|g' '{}' +

para ter find executando o comando sed com todos os nomes de arquivos encontrados. Os nomes dos arquivos são inseridos no lugar de {} e + significa find minimizará o número de vezes que ele executa o comando.

-execdir pode ser melhor que -exec por certos motivos de segurança descritos na find man page ; é uma extensão não padrão, mas como você parece estar usando ferramentas GNU, ela deve estar lá para você, se você precisar.

    
por 20.08.2014 / 10:53
2

É a barra invertida. A barra invertida desativa o próximo caractere e o faz perder significados especiais. O comando sed está lendo o que você digitou como (apenas a expressão sed aqui, não estou fazendo toda a tediosa linha de comando do shell):

s
<SPACE>
C
:
Literal <SPACE>
/root/
<SPACE>

Você disse sed que deseja usar como o marcador da expressão que está procurando e a substituição. Mas o sed espera ver algo como:

s
<SPACE>
C
:
Literal \
<SPACE>
/root/
<SPACE>

Para transformar a barra invertida em uma barra invertida literal, adicione-a com uma barra invertida:

sed -e 's C:\ /root '

Pessoalmente, prefiro evitar usar um espaço. Eu usaria algo como | ou ; . Mas você ainda tem um problema com a barra invertida. O que é realmente divertido é descobrir o que você teria que digitar para usar uma barra invertida como separador. :)

    
por 20.08.2014 / 11:06

Tags