【问题标题】:backslash in $ python -c "script"$ python -c“脚本”中的反斜杠
【发布时间】:2013-08-23 12:16:08
【问题描述】:

今天我编写了一个 Python 脚本来处理数据并以自定义格式打印它们。它在交互式 Python 下按预期工作。然后我继续尝试在终端中将输出重定向到一个文本文件,并遇到了一些意想不到的事情。

我尝试的特定示例是按列排列数据列表,并以 LaTeX 表格格式打印它们。它的工作方式或多或少类似于:

foo(mylist, sep_col='\t', sep_row=r'\\ \hline')

当我尝试在终端中运行脚本时,我这样做了:

$ python -c "from foo import foo; foo(mylist, col_sep=' & ', row_sep=r' \\ \hline')" > results.txt

但原来\\ \hline部分显示为\ \hline,和交互式Python下不一样。

当我更多地研究问题(或者可能是背后的原理)时,我发现$ python -c处理的Python脚本的行为在交互式Python下是不一样的。

在交互式 Python 下:>>> print r'\\' 给出\\

但是,在终端中,$ python -c "print r'\\'" 引发了 SyntaxError

  File "<string>", line 1
    print r'\'
             ^
SyntaxError: EOL while scanning string literal

当反斜杠的数量为 3 或 4 时,终端似乎给出了\\。数字 5 或 6 会引发错误。 7个反斜杠给\\\\,也就是说在这种环境下没有办法给\\\

我已经搜索这个问题很长时间了,但似乎很少有人谈论$ python -c。如果我复制了,请提前道歉。

【问题讨论】:

    标签: python shell terminal latex backslash


    【解决方案1】:

    在终端中,说:

    $ python -c "print r'\\'"
      File "<string>", line 1
        print r'\'
                 ^
    SyntaxError: EOL while scanning string literal
    

    由于 shell 起作用而导致错误。它将\\翻译\(仔细查看错误消息)。

    相反,说

    $ python -c 'print r"\\"'
    \\
    

    从 shell 运行时,即在单引号中提供命令,在双引号中提供 print 的参数。

    您在交互模式下执行的命令相当于:

    $ python -c "print r'\\\\'"
    \\
    

    编辑:This 答案解释了为什么原始字符串不能有奇数个反斜杠。

    而且,这在官方FAQ中也有说明。

    【讨论】:

    • 感谢您的回答。但是等等,为什么它仍然对$ python -c 'print r"\\\"' 不起作用?
    • @kctong529 FAQ 也解释了。
    • 顺便说一句,您认为将包含反斜杠的原始字符串作为argv 的某些参数传递给Python 脚本是一个好习惯吗?
    • 我会避免这样做。
    【解决方案2】:

    您的 shell 也会解释双引号内的反斜杠。您可以使用单引号来避免这种情况;那么您将不得不将python脚本中的单引号更改为双引号:

    python -c 'from foo import foo; foo(mylist, col_sep=" & ", row_sep=r" \\ \hline")'
    

    在这种情况下,您可以使用echo 调试:只需在您的 shell 命令前写上echo 即可查看将要执行的内容:

    echo python -c "print r'\\'"
    

    显示:

    python -c print r'\'
    

    【讨论】:

    • 你的意思是单引号对 shell 解释的意义大于双引号? echo 调试有帮助。但是显示python -c print r"\\\"echo python -c 'print r"\\\"' 仍然会引发SyntaxError
    • 是的,单引号和双引号在shell中有不同的含义(但这不是这里的主题)。您示例中的 python -c print r"\\\" 是语法错误,因为它包含未终止的字符串;它的开头是这样的:反斜杠(由其中两个表示),双引号(由黑斜杠和双引号表示),然后缺少结束双引号。像这样尝试:print "\\\"" 这应该可以。
    【解决方案3】:

    您的终端无法识别原始字符串或正则表达式字符串,即 r'something' 任何特殊内容,并且所有反斜杠都需要在终端中通过反斜杠进行转义,因此:

    python -c "from foo import foo; foo(mylist, col_sep=' & ', row_sep=r' \\ \hline')" > results.tx
    

    需要:

    python -c "from foo import foo; foo(mylist, col_sep=' & ', row_sep=r' \\\\ \\hline');" > results.tx
    

    foo(mylist, sep_col='\t', sep_row=r'\\ \hline')
    

    将映射到:

    python -c "from foo import foo; foo(mylist, sep_col='\\t', sep_row=r'\\\\ \\hline');"
    

    【讨论】:

    • 这是有道理的,只是我没有意识到这一事实(终端无法识别原始字符串或正则表达式字符串)。你认为使用原始字符串作为一种习惯是不明智的吗?
    • 不在 python 中 - 从终端调用时没有它们 row_sep 将是 '\\\\\\\\\\\\\\hline' 即 python 翻倍,终端翻倍。
    猜你喜欢
    • 2020-02-11
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    • 2011-05-16
    相关资源
    最近更新 更多