将部分模式从 sed 传递到 shell [英] Passing part of patterns from sed to shell

查看:49
本文介绍了将部分模式从 sed 传递到 shell的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a file which contains lines of the following format:

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

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

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

Each word (token) in the line (e.g. w1#1#x) is made of 3 parts, the first showing some index (w1 in this case), the second is an integer (1 in this case) , and the third is a character (x in this case)

现在,对于每个单词(标记),我需要打印一个附加字段,该字段将根据第二部分和第三部分的值进行计算(,第四部分将是第二部分的函数和第三部分),输出文件应如下所示:

Now, for each word (token), I need to print an additional field which will be calculated based on value of second and third part (i.e., the 4th part will be a function of 2nd and 3rd part), and the output file should look like:

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

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

哪里

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

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

现在,使用 sed 模式,我可以识别每个单词(标记)中的组成部分,例如,

Now, using the sed patterns I can identify the components in every word (token), e.g.,

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

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

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

where \2 and \3 are parts of the pattern (I am calling them parts of the pattern because of this link)

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

Now, I need to compute the 4th part using \2 and \3. I have defined a shell function getInfo() which takes 2 arguments and does the required computation and gives me back the 4th part. The problem is inserting this function in the sed command. I tried following:

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

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

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

but this is not working. Shell is not receiving the parts of the pattern as arguments.

所以问题是:

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

How to pass the sed parts of the pattern to a shell (function)?

我可以轻松编写一个 shell 脚本,该脚本可以逐字拆分行并完成所需的工作,然后将文件缝合回去,但是如果 shell 可以接收部分模式 作为 sed 命令中 sed 的参数.

I can easily write a shell script which would split the line word-by-word and do the required job and then stitch the file back, but I would really appreciate if shell can receive parts of the pattern as arguments from sed within the sed command.

问候,

萨利尔·乔希

推荐答案

sed 不再是 工作.我认为这项任务已经达到了这一点(但请参阅聪明的 answer by potong 这表明它可以用 bash 和 <代码>sed).

There comes a point at which sed is no longer the correct tool for the job. I think this task has reached that point (but see the clever answer by potong which shows that it can be done with bash and sed).

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

Which alternative tool do you use? You don't show the function, but if it can be conveniently calculated in the shell with a shell function, the chances are that awk is powerful enough to do the job. I'd probably fall back on Perl myself, but Python (or Ruby) would also work well. All of these allow you to write a function, to read the data and apply the function to the data before writing the data back out.

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

The problem with trying to use a function in sedis that it has no mechanism to define functions or to execute shell functions. To use sed, you'd have to think in terms of two passes through the data, the first extracting the (unique) tokens for subsequent processing, which would be to apply the shell function to each token, generating a sed script which simply matches each token and substitutes it with its replacement, followed by applying that script in the second pass over the data.

这篇关于将部分模式从 sed 传递到 shell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆