Como escapar de caracteres especiais em uma string?

Presumindo $file mantendo o valor de um nome de arquivo, diga Dr" A.tif. Na programação bash, como poderia escapar das aspas simples e qualquer outro caractere especial de $file sem remover o caractere especial?

Atualização em 9 de julho de 2014

Conforme solicitação de @Gilles , seguinte snippet de código que não “é capaz de lidar com Dr" A.tif:

files=$(find /path/ -maxdepth 1 -name "*.[Pp][Dd][Ff]" -o -name "*.[Tt][Ii][Ff]") echo "${files}" > ${TEMP_FILE} while read file do newfile=$(echo "${file}" | sed "s, ,\\ ,g") ## line 1 done < ${TEMP_FILE} 

Depois de experimentar o resposta de @Patrick em line 1, parece funcionar para mim. Mas se eu tiver um arquivo como Dr\^s A.tif, printf o comando não parece ajudar, ele me mostra Dr\^s\ A.tif. Se eu tentar manualmente no console desta forma:

printf "%q" "Dr\^s A.tif"

Eu terei esta saída:

Dr\\\^s\ A.tif

Alguma ideia de como lidar com isso?

Comentários

  • em que contexto que você espera usar $ file? ou este problema está atribuindo a string com o caractere especial para $ file?
  • Na verdade, o comando find me retorna um array da lista de arquivos. E então eu faço um loop por esta lista de arquivos na variável $ file.
  • Você ' recebeu algumas respostas corretas aqui, mas provavelmente não são as respostas para o pergunta que você ' está realmente perguntando. Pelo seu comentário aqui, suspeito fortemente que você ' está no caminho errado. Não podemos ' não ajudá-lo muito porque você não mostra seu código constantemente. No entanto, recomendo que você leia Por que meu script de shell bloqueia com espaços em branco ou outros caracteres especiais? como plano de fundo. Mostre seu script e explique o que você deseja fazer.

Resposta

Você pode usar o printf integrado com %q para fazer isso. Por exemplo:

$ file="Dr" A.tif" $ printf "%q\n" "$file" Dr\"\ A.tif $ file=" foo$bar\baz`" $ printf "%q\n" "$file" \ foo\$bar\\baz\` 

Da documentação do bash em printf:

In addition to the standard format specifications described in printf(1) and printf(3), printf interprets: %b expand backslash escape sequences in the corresponding argument %q quote the argument in a way that can be reused as shell input %(fmt)T output the date-time string resulting from using FMT as a format string for strftime(3) 

Comentários

  • Este não ' não funciona com certos casos. quando você precisa preservar as aspas duplas.
  • @ user3467349 funciona muito bem com aspas. Eu ' aposto que você ' está tentando algo como printf '%s' "foo". Você precisa entender como a análise de argumentos funciona no shell primeiro. Veja gnu.org/software/bash/manual/bash.html#Shell-Operation # 2 acontece antes de # 6.
  • Você pode forneça um exemplo desta string impressa com printf e nenhuma outra manipulação It doesn't have a: ""
  • Seu problema não tem nada a ver com printf. Seu problema é que você não ' quer que o shell analise sua string. Para fazer isso, você deve passar sua entrada para o shell de uma forma que ele não ' nem tente analisá-la. Uma maneira de fazer isso seria read -r -p 'input: ' && printf '%q\n' "$REPLY" e fornecer a entrada quando solicitado.
  • Como eu ' eu disse várias vezes agora. Não saber como passar dados brutos para o shell não é ' um problema com printf. Talvez você deva fazer uma pergunta em vez de criticar uma solução que não tem nada a ver com o seu problema.

Resposta

Experimente: –

file=Dr\"\ A.tif echo $file Dr" A.tif 

ou

file="Dr" A.tif" echo $file Dr" A.tif 

ou se a string contiver um duplo citação: –

file="Dr" A.tif" echo $file Dr" A.tif 

Existem bons tutoriais sobre como escapar e citar na rede. Comece com este .

Resposta

Você não “não é necessário escapar de nenhum nome de arquivo que você esteja manipulando em um script. O escape é necessário apenas se você quiser colocar um nome de arquivo como literal em um script ou passar vários nomes de arquivo como um único fluxo de entrada para outro script.

Como você está repetindo a saída de find, isso é uma das maneiras mais simples (!) de lidar com todos os caminhos possíveis :

while IFS= read -r -d "" do file_namex="$(basename -- "$REPLY"; echo x)" file_name="${file_namex%$"\nx"}" do_something -- "$file_name" done <(find "$some_path" -exec printf "%s\0" {} +) 

Resposta

rápida e (muito) suja

find . | sed "s/^/"/" | sed "s/$/"/" 

Resposta

Muitas dessas respostas, incluindo a mais votada usando printf "%q", não funciona em todos os casos sem manipulação adicional.Eu sugeriria o seguinte (exemplo abaixo):

cat <<EOF; 2015-11-07T03:34:41Z app[postgres.0000]: [TAG] text-search query doesn"t contain lexemes: "" EOF

Comentários

  • Desculpe a pergunta n00b, mas você pode explicar como você realmente usaria isso para escapar caracteres em uma string? Se eu copiar o código que você escreve em meu terminal, ele apenas imprimirá 2015-11-07T03: 34: 41Z app [postgres.0000]: [TAG] consulta de pesquisa de texto não ' t contêm lexemas: " " … nada é escapado.
  • Isso ' é literalmente o ponto, todos os caracteres especiais são interpretados como caracteres literais, não por seu significado especial. Tente echo " a string acima " para ver a diferença.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *