Sed替换最后一个逗号失败

时间:2017-06-13 13:54:12

标签: sed

我正在研究一个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脚本的第一行没有ap有关,但我不希望它打印这些值,我希望它们被发送到脚本中的下一行(isn'那是默认的?)

编辑: [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'

(注意缺少尾随逗号)

1 个答案:

答案 0 :(得分: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%, }

OR

RESULT=${RESULT::-2}