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çãoIt 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 seriaread -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.