我需要一个 Bash 命令来将字符串转换为转义的内容。这是一个例子:
echo "hello\world" | escape | someprog
转义命令使
"hello\world"
变成 "hello\\\world"
。然后,someprog 可以按预期使用 "hello\\world"
。当然,这是我真正要做的事情的一个简化示例。
在 Bash 中:
printf "%q" "hello\world" | someprog
例如:
printf "%q" "hello\world"
hello\\world
这也可以通过变量使用:
printf -v var "%q\n" "hello\world"
echo "$var"
hello\\world
纯 Bash,使用参数替换:
string="Hello\ world"
echo ${string//\\/\\\\} | someprog
bash 内置
${…@Q}
扩展已在不久前添加:
echo "hello\\world" | ( read -rsd '' x; echo ${x@Q} )
'hello\world'
转义的输出是 bash 格式,因此它可能不是您需要的。
这可能不是您想要的,因为它不是任何人系统上的标准命令,但由于我的程序应该在 POSIX 系统上正常工作(如果已编译),所以无论如何我都会提到它。如果您有能力在相关机器上编译或添加程序,它应该可以工作。
我已经使用它大约一年了,没有出现任何问题,但它可能无法处理某些边缘情况。最具体地说,我不知道它会对字符串中的换行符做什么;可能需要添加
\\n
的情况。这个字符列表并不具有权威性,但我相信它涵盖了其他所有内容。
我专门将其编写为“帮助程序”程序,以便我可以为
scp
命令等内容制作包装器。
它也可以作为 shell 函数实现
因此我提出
escapify.c
。我这样使用它:
scp user@host:"$(escapify "/this/path/needs to be escaped/file.c")" destination_file.c
请注意:我制作此程序供我个人使用。它还会(可能错误地)假设,如果给定多个参数,它应该只打印一个未转义的空格并继续。这意味着它可以用于正确传递多个转义参数,但可能被某些人视为不需要的行为。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
char c='\0';
int i=0;
int j=1;
/* do not care if no args passed; escaped nothing is still nothing. */
if(argc < 2)
{
return 0;
}
while(j<argc)
{
while(i<strlen(argv[j]))
{
c=argv[j][i];
/* this switch has no breaks on purpose. */
switch(c)
{
case ';':
case '\'':
case ' ':
case '!':
case '"':
case '#':
case '$':
case '&':
case '(':
case ')':
case '|':
case '*':
case ',':
case '<':
case '>':
case '[':
case ']':
case '\\':
case '^':
case '`':
case '{':
case '}':
putchar('\\');
default:
putchar(c);
}
i++;
}
j++;
if(j<argc) {
putchar(' ');
}
i=0;
}
/* newline at end */
putchar ('\n');
return 0;
}
可以使用perl来替换各种字符,例如:
$ echo "Hello\ world" | perl -pe 's/\\/\\\\/g'
Hello\\ world
根据转义的性质,您可以链接多个调用来转义正确的字符。