【问题标题】:Sed replacing last comma failsSed 替换最后一个逗号失败
【发布时间】:2017-06-14 00:17:48
【问题描述】:

我正在编写一个 sed 脚本,该脚本需要一堆行并将它们转换为 matlab 的参数列表(单引号,逗号分隔)。

目前运行良好:

[script to generate list] | sed -n "s#\(.*$\)#'\1',#p#" | tr '\n' ' '

但这给我留下了一个逗号。

通过测试,我可以删除它

[list of comma separated values] | sed -n 's#,$##p#'

但是,当把它们放在一起时:

[script to generate list] | sed -n "s#\(.*$\)#'\1',#;s#,$##p#" | tr '\n' ' '

什么都不输出。

我觉得这与 sed 脚本的第一行中没有 p 有关,但我不希望它打印这些值,我希望它们发送到脚本的下一行(不是t 那是默认的吗?)

编辑: [script to generate list] 输出目录列表,例如:

./work/matlab_stun_gun/tex/fullTest.pdf
./Downloads/Howfar(tetra2) fixed.pdf
./work/savdocs/win_tests/tex/texReport.pdf
./Downloads/AcademicAudit.pdf
./work/matlab_stun_gun/report.pdf
./Downloads/PMB_4DVMC.pdf
./work/savdocs/win_tests/tex/mouseHeatMap.pdf
./Downloads/Geometry.pdf
./work/savdocs/win_tests/tex/mouseHeatMap.pdf
./work/matlab_stun_gun/tex/fullTest.pdf

列表生成器只是find . -name "*.pdf" | pickl -n 10,根据文件类型/编号等进行了调整。这将成为一个通用脚本。

预期的输出是:

'./work/savdocs/win_tests/tex/mClickss.pdf', './Downloads/Howfar(tetra2) fixed.pdf', './Downloads/MedPhys_defDOSXYZ.pdf', './Downloads/MedPhys_defDOSXYZ.pdf', './report.pdf', './work/savdocs/win_tests/tex/cSwitchs.pdf', './tex/zoomIn.pdf', './tex/fullTest.pdf', './temp/tex/zoomIn.pdf', './tex/zoomIn.pdf'

(注意后面没有逗号)

【问题讨论】:

  • 为什么tr 命令后面有括号?
  • 这是一个复制错误 - 整个内容都在 $() 中。已编辑
  • 为清楚起见添加预期输出..
  • 你忘了修复第二个。
  • 您的输入与输出不匹配:)

标签: sed


【解决方案1】:

您在这里遇到了一个多方面的问题,从某种意义上说,您的每次尝试都有问题。

[list of comma separated values] | sed -n 's#,$##p#' 开头,请记住tr 有效地使您的分隔符', '(逗号-空格)而不仅仅是',' 逗号。这意味着您将不会从第二个 sed 表达式中输出任何内容。您可以通过匹配sed -n 's#, $##p#' 来解决此问题。如果您坚持使用-n 标志,那是正确的解决方案。全文:

[script to generate list] | \
        sed -n "s#\(.*$\)#'\1',#p#" | \
        tr '\n' ' ' | \
        sed -n 's#, $##p#'

您的组合尝试[script to generate list] | sed -n "s#\(.*$\)#'\1',#;s#,$##p#" | tr '\n' ' ' 的问题是您需要在删除尾随逗号之前应用tr 。即使这要打印任何内容,您也将添加一个逗号,在每一行上立即将其去掉,然后用空格替换换行符。上面已经显示了正确的顺序。

sed 中的多个命令应使用-e 标志指定。它们将一个命令的结果通过管道传输到另一个命令,相当于使用管道,但效率更高。要让sed -n "s#\(.*$\)#'\1',#;s#,$##p#" 打印,请将其改写为:

sed -n -e "s#\(.*$\)#'\1',#" -e "s#, $##p#"

这当然会在您将逗号添加到每一行后立即删除它们,但它显示了这样做的正确语法。

进一步改进

您可能不需要将-n 标志用于sed(因此)/p/ 标志用于s 命令。 -n 标志仅在您只想打印匹配项但又想打印所有内容时才有用,因此它不适用于您。

您也不需要显式捕获组,因为您可以使用 \0 替换来获取整个匹配项,而不仅仅是组。这是一个例子:

[script to generate list] | sed "s/.*/'\0'" | tr '\n' ' ' | sed 's/, $//'

最后,有一些替代方法可以在不启动子进程的情况下删除字符串的尾随位,尤其是因为您已经将表达式包含在 $(...) 中:

RESULT=$([script to generate list] | sed "s/.*/'\0'" | tr '\n' ' ')
RESULT=${RESULT%, }

RESULT=${RESULT::-2}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-02
    • 2011-06-18
    • 1970-01-01
    • 2019-07-01
    • 2012-12-16
    • 2015-06-19
    • 1970-01-01
    相关资源
    最近更新 更多