将部分模式从sed传递到shell

Sal*_*lil 5 shell sed

我有一个文件,其中包含以下格式的行:

w1#1#x w2#4#b w3#2#d ......

行中的每个单词(标记)(例如w1#1#x)由3个部分组成,第一个显示一些索引(在这种情况下为w1),第二个是整数(在这种情况下为1),第三个是一个字符(在这种情况下为x)

现在,对于每个单词(标记),我需要打印一个额外的字段,它将根据第二和第三部分的值计算(第四部分将是第二和第三部分的函数),输出文件应该看起来像:

w1#1#x#f1 w2#4#b#f2 w3#2#d#f3 ...

哪里

f1 =函数(1,x),f2 =函数(4,b),f3 =函数(2,d)

现在,使用sed模式我可以识别每个单词(令牌)中的组件,例如,

echo $ line | sed"s /([^#] )#([^#])#([^#]*)/\1#\ 2#\ 3/g"

其中\ 2和\ 3是模式的一部分(由于此链接,我将它们称为模式的一部分)

现在,我需要使用\ 2和\ 3来计算第四部分.我已经定义了一个shell函数getInfo(),它接受2个参数并执行所需的计算并返回第4部分.问题是在sed命令中插入此函数.我试过以下:

echo $ line | sed"s /([^#] )#([^#])#([^#]*)/\1#\ 2#\ 3`getInfo\2\3`/g"

但这不起作用.Shell没有接收模式部分作为参数.

所以问题是:

如何将模式的sed 部分传递给shell(函数)?

我可以轻松编写一个shell脚本,它会逐行拆分行并执行所需的工作,然后将文件缝合回来,但我真的很感激shell是否可以从sed命令中的sed 接收模式的一部分作为参数.

问候,

Salil Joshi

pot*_*ong 6

这可能对你有用:

func(){ echo "$1#$2#$3#$2$3"; }
export -f func
echo "w1#1#x w2#4#b w3#2#d" |
sed 's/\([^#]*\)#\([^#]*\)#\([^ ]*\) \?/echo -n "$(func \1 \2 \3) "; /g;s/$/echo ""/' |
sh
w1#1#x#1x w2#4#b#4b w3#2#d#2d 
Run Code Online (Sandbox Code Playgroud)

或者如果你有GNU sed:

func(){ echo "$1#$2#$3#$2$3"; }
export -f func
echo "w1#1#x w2#4#b w3#2#d" |
sed 's/\([^#]*\)#\([^#]*\)#\([^ ]*\) \?/echo -n "$(func \1 \2 \3) "; /ge;s/.$//'
w1#1#x#1x w2#4#b#4b w3#2#d#2d
Run Code Online (Sandbox Code Playgroud)

  • +1这是一个巧妙的演示,它可以通过足够的技巧来实现`sed`.然而,绝对是(IMO)超越了明智的限制.特别是,如果数据文件包含shell元字符,那么执行shell函数可能会很危险.如果数据只是具有简单空格和字母数字的多哈希条目,那么你就可以了. (2认同)

Jon*_*ler 3

到了一定程度,它就sed不再是完成这项工作的正确工具了。我认为这个任务已经达到了这一点(但请参阅potong的聪明答案,它表明它可以用和 来完成)。bashsed

您使用哪种替代工具?您没有显示该函数,但如果可以使用 shell 函数在 shell 中方便地计算它,那么该函数很可能awk足够强大来完成这项工作。我自己可能会求助于 Perl,但 Python(或 Ruby)也能很好地工作。所有这些都允许您编写一个函数,读取数据并将该函数应用于数据,然后再将数据写回。

尝试使用函数的问题在于sed它没有定义函数或执行 shell 函数的机制。要使用sed,您必须考虑两次遍历数据,第一次提取(唯一的)标记以进行后续处理,即将 shell 函数应用于每个标记,生成一个sed仅匹配每个标记的脚本并用其替换项替换它,然后在第二次数据传递中应用该脚本。

  • 正确 - 答案是(对于所有实际目的)否。如果是生死攸关的情况,无法使用 Perl、Awk、Python,那么可以使用 `sed`、`uniq 设计多步骤方案`、`sort`、你的 shell 函数等等。但是除非可用的工具集有愚蠢的限制,否则 `sed` 这次不是正确的答案。 (2认同)