citar citações e barras invertidas no cygwin

1

Eu estou tentando extrair uma substring de uma string com sed no cygwin.

#!/bin/bash

var1="foo\ bar"
var2="baz"

var3="$var1 $var2"

# extract "foo\ bar" from "foo\ bar baz"
var4='echo $var3 | sed "s/"$var1"//"'
echo "$var4"

mas recebo a seguinte saída, causada pela barra invertida:     sed: -e expressão # 1, char 6: comando 'não terminado'

como posso escrever o comando sed para a saída 'baz'?

    
por elSnape 12.06.2013 / 20:48

3 respostas

2

O problema é que tanto o shell quanto o sed interpretam as barras invertidas. Você pode conseguir sed para fazer isso corretamente, mas eu recomendaria simplesmente usar uma ferramenta diferente, por exemplo, Perl:

#!/bin/bash
export var1="foo\ bar" ## The export allows Perl to access the variable as $ENV{var1}
var2="baz"
var3="$var1 $var2"

# extract "foo\ bar" from "foo\ bar baz"
var4='echo $var3 | perl -ne '$var1=quotemeta($ENV{var1}); s/$var1//; print''
echo "$var4"

O exemplo acima usa a função quotemeta do Perl que escapa de todos os caracteres não-ASCII, permitindo que o regex corresponde corretamente a barra invertida.

Finalmente, por que você quer fazer isso? Você realmente precisa coincidir com o \ ou você está tentando corresponder espaços em seqüências de bash? Existem maneiras mais fáceis, se assim for.

    
por 12.06.2013 / 21:10
1

para colocá-lo simplesmente .... sed não funciona ... como em coloumns, sua abordagem mais orientada a linha. Não force um comando - use-o onde estiver adequado. Cortar seria uma opção melhor / mais simples

alternativamente, se a extração de substring for o que você está procurando, então o awk também é adequado para isso ... exemplo

Kaizen ~/so_test
$ echo "foo\ bar baz" | awk '{print substr($0,1,8)}'
+ echo 'foo\ bar baz'
+ awk '{print substr($0,1,8)}'
foo\ bar

é mais simples de usar neste caso, isso é suficiente?

    
por 12.06.2013 / 21:09
0

Para fazer isso funcionar com sed, precisamos escapar das barras invertidas. Prepare-se para a loucura:

$ echo "$var1"
foo\ bar
$ echo "$var3"
foo\ bar baz
$ echo "$var3" | sed "s/$var1//"
foo\ bar baz
$ echo "${var1//\/\\}"
foo\ bar
$ echo "$var3" | sed "s/${var1//\/\\}//"
 baz

Naturalmente, há muitos outros caracteres que também exigem escape, como * , então a resposta perl de @ terdon é melhor do que essa floresta de palito.

    
por 12.06.2013 / 22:59

Tags