2011-07-28 34 views
0

假设我有一个输入流,其中包含分隔成一定数量字段的行。我想剪切各个领域,向某个程序(假定每个输入行返回一行)输入某个字段(或多个字段),并将其他字段保持原样并粘贴到一起。我大概可以想象一些令人费解的解决方案,但这应该是一种干净自然的方式。在命令中输入输入流的某个字段,并粘贴结果

作为一个具体的例子,说我有生产形式的线方案:

$ inputprog 
<a> hello world! 
<b> hi everyone! 
<a> hi! 

说我希望把消息中大写,而离开第一场不变。这里是我想象的事情:

$ inputprog | program -d' ' -f2- "tr a-z A-Z" 
<a> HELLO WORLD! 
<b> HI EVERYONE! 
<a> HI! 

我要寻找一个合理的清洁方法近似program。 (我对这个例子特有的解决方案不感兴趣。)

在此先感谢您的帮助!

回答

1

awk可以做你想做的。例如:

$ echo "field1 field2" | awk '{$2 = toupper($2); print;}' 
field1 FIELD2 

非常接近你想要做的事情。 $2 = toupper($2);改变第二个字段,而print打印出整个(修改)的行。

但是,您在如何定义“字段”时遇到了问题。在上面的例子中,字段之间用空格隔开(你可以用如下方式将字段分隔符更改为任意正则表达式:-F'<[a-zA-Z]+>' - 这将被视为字段分隔符)。 但在您的示例中,您似乎将<a>视为一个字段,将hello world!视为另一个字段。任何程序只能通过疯狂的猜测来达到你想要的行为。为什么world!不被认为是第三个领域? 因此,如果你能得到一个明确的分隔领域政策的输入,awk正是你想要的。

查看页面,如http://people.cs.uu.nl/piet/docs/nawk/nawk_92.html(awk字符串函数)和http://www.pement.org/awk/awk1line.txt(awk 1行)以获取更多信息。

BTW,人们还可以通过遍历除第一个所有领域作出上述工作的具体例子(NF ==场数):

$ echo "<a> hello world! 
<b> hi everyone! 
<a> hi" | 
awk '{for(i=2;i<=NF;++i) { $i=toupper($i); }; print;}' 
<a> HELLO WORLD! 
<b> HI EVERYONE! 
<a> HI 

即使你不感兴趣的解决方案这个例子。 ;-)

P.S:sed也应该能够做的工作(http://en.wikipedia.org/wiki/Sed)

+0

感谢您给我们详细的答复!我知道'sed'和'awk',但我真的需要将该字段转换为我有的用例的外部程序。 'toupper()'适用于这种简单的情况,但是'awk'内置对于我想做的事来说是不够的。但是,awk似乎具有将字段传递给外部命令的功能,我可以用它来做我想做的事情。谢谢你给我这个主意! :-) – a3nm

相关问题