【问题标题】:Use of bash program with argument inside a sed在 sed 中使用带有参数的 bash 程序
【发布时间】:2016-01-29 22:15:09
【问题描述】:

我有一个小问题要问你。 但首先,我知道还有其他方法可以做我想做的事情(我已经制作了一个小的 python 脚本来做到这一点),但是出于我自己的好奇心,我想知道是否有办法做使用 SED。

所以,例如:这是一个 CSV 文件,例如:

12345678,yan solo
23456789,luke skywalker
34567890,leia organa

这里有一个名为“SOMESCRIPT”的 bash 脚本,它会将参数转换为其他内容。例如。 :

~$ ./SOMESCRIPT 12345678
abcd

所以,我想要做的是:使用 SED 内部的脚本重新生成具有转换值的 CSV。

这里是输出示例:

abcd,yan solo
efgh,luke skywalker
ijkl,leia organa

一些想法:

~$ cat somecsv.csv | sed "s/\(.*\),/\1/g"

--> 正则表达式捕获要转换的部分并将其保存到\1中的堆栈中

~$ cat somecsv.csv | sed "s/\(.*\),/`SOMESCRIPT `\1/g"

--> 对于每一行,SOMESCRIPT 被执行,但在 \1 的打印之前

~$ cat somecsv.csv | sed "s/\(.*\),/`SOMESCRIPT \1`/g"

--> 对于每一行,SOMESCRIPT 都会执行,但是 \1 不被识别为 shell 变量

所以,基本上,问题是:是否可以将堆栈值 \1 作为 shell 参数传递给 SOMESCRIPT ?

【问题讨论】:

    标签: regex bash shell sed


    【解决方案1】:

    使用GNU sed 您可以将e 选项传递给s 命令,这使得sed 将替换结果作为shell 命令执行:

    sed 's#.*#./SOMESCRIPT "\0"#e'
    

    您也可以使用awk 来完成这项工作。在 awk 程序中,您可以使用 system() 函数通过 shell 执行外部命令:

    awk -F, '{system("./SOMESCRIPT \""$1"\"")}'
    

    shell本身也可以做到:

    #!/bin/bash
    while IFS="," read a b c ; do
        ./SOMESCRIPT "$a"
    done < some.csv
    

    毕竟我喜欢 shell 解决方案,因为它正确地逃避了 SOMESCRIPT 的论点 - 设计使然。

    【讨论】:

    • 在 shell 本身中执行此操作要干净得多 +1
    • 是的。毕竟我也得出了这个结论。
    • 感谢您的回答。这并不完全按照我想要的方式工作,但这是一个很好的起点
    • 感谢 awk 和 while 之类的替代方案,我知道这可以工作,但最初的问题是使用 SED 来做到这一点。
    【解决方案2】:

    这可能对你有用(GNU sed):

    sed 's/\(.*\)\(,.*\)/printf "%s\2\\n" $(SOMESCRIPT "\1")/e' file
    

    这使用 GNU 特定的 e 标志/命令。如果您从替换命令中删除它,则 sed 命令的输出可以通过管道传输到执行相同操作的 bash 命令中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-16
      • 2011-10-25
      • 2014-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多