对于bash的printf%q,是否有任何csh替代方法?

时间:2016-05-23 03:43:19

标签: shell csh

Bash的内置命令printf支持%q格式字符串,它转义shell输入变量的内容。

我尝试了一些选项::q只转义了空格,而gnu printf不支持%q

目前,我使用以下代码:

set valq = `echo $val:q | bash -c 'read q;printf %q "$q"'`
/path/to/executable $valq 

我不喜欢有bash依赖性的csh脚本。这有什么csh原生解决方案吗?

感谢。

这是一个测试代码,用于说明我遇到的问题。

wrapper.csh

#!/bin/csh -f
set i = 1
set tst1 = ""
set tst2 = ""
while ( $i <= $#argv )
    set arg = "$argv[$i]"
    set tst1 = ($tst1:q $arg:q)
    set arg2 = `echo $arg:q | bash -c 'read q;printf %q "$q"'`
    set tst2 = "$tst2:q $arg2:q"
    @ i = $i + 1
end
echo "====case 1===="
./test.csh $tst1:q
./test.csh $tst1
./test.csh $tst2
echo "====case 2===="
csh -cf "./test.csh $tst1"
csh -cf "./test.csh $tst1:q"
csh -cf "./test.csh $tst2"

test.csh

#!/bin/csh -f
echo -n "TEST ARG:"
set i = 1
while ($i <= $#argv)
    echo -n "${i}:$argv[$i] "
    @ i = $i + 1
end
echo

测试结果1:     >./wrapper.csh "a ()" b c

====case 1====
TEST ARG:1:a () 2:b 3:c
TEST ARG:1:a 2:() 3:b 4:c
TEST ARG:1:a\ 2:\(\) 3:b 4:c
====case 2====
Badly placed ()'s.
Badly placed ()'s.
TEST ARG:1:a () 2:b 3:c

测试结果2:     bash>./wrapper.csh "'\"a ()" b c csh>./wrapper.csh "'"'"'"a ( ) " b c

====case 1====
TEST ARG:1:'"a () 2:b 3:c
TEST ARG:1:'"a 2:() 3:b 4:c
TEST ARG:1:\'\"a\ 2:\(\) 3:b 4:c
====case 2====
Unmatched '.
Unmatched '.
TEST ARG:1:'"a () 2:b 3:c

测试摘要:

  • 如果在csh中直接调用命令,则$val:q是正确的用法。

  • 如果命令是通过参数传递的,则printf %q是正确的用法。

1 个答案:

答案 0 :(得分:0)

只需使用/path/to/executable "$val"

更新

如果变量在"内扩展(如在csh -cf "test.csh $tst1"中),并且要保留特殊字符和多个单词,则必须确实引用这些单词。但printf的特殊bash对此并不是必不可少的;我们可以做到这一点。 G。用:

set tst1q=`printf " '%s'" $tst1:q`
csh -cf "test.csh $tst1q"

(正常printf没有%q)。

更新

要同时允许"',您可以在最初执行

之后
    set s='s/[] "$&-*;<>?`|~[]/\\&/g'

bash -c 'read q;printf %q "$q"'替换为sed "$s"中的wrapper.csh

正则表达式

[] "$&-*;<>?`|~[]

括号表达式[]中包含的字符列表。它匹配单个字符,该字符由替换\\&加上反斜杠(特殊字符&表示匹配的字符)。我没有包含字符,^(它们由printf %q转义,但在csh中不需要),而我包括~(它不会被printf %q转义,但必须位于csh - 尝试wrapper.csh "~")。