如何将程序应用于bash/awk中文本中的列



我有一个包含以下内容的文本:

column1 column2 column3 column4
text1.1 text1.2 text1.3 text1.4
text2.2 text2.2 text2.3 text3.4

我想执行一个程序,将第2列中的所有文本转换为新文本。该程序获取stdin并返回stdout,因此它的调用方式如下:echo"text-to-transform" | myprogram,并将"transformed-text"返回到stdout。

将myprogram应用于column2并在bash中显示输出的最简单方法是什么?

输出看起来像这个

column1 column2 column3 column4
text1.1 transformed-text1.2 text1.3 text1.4
text2.2 transformed-text2.2 text2.3 text3.4

我猜是awk,但我对它了解不够。

感谢

$ cat tst.awk
BEGIN { myprogram = "tr [:lower:] [:upper:]" }
NR>1 {
cmd = "printf 47%sn47, 47" $2 "47 | " myprogram
if ( (cmd | getline line) > 0 ) {
$2 = line
}
close(cmd)
}
{ print }
$ awk -f tst.awk file
column1 column2 column3 column4
text1.1 TEXT1.2 text1.3 text1.4
text2.2 TEXT2.2 text2.3 text3.4

myprogram = "tr [:lower:] [:upper:]"替换为myprogram = "<whatever your real program is called>"。如果你喜欢,你甚至可以参数化它:

$ cat tst.awk
NR>1 {
cmd = "printf 47%sn47, 47" $col "47 | " myprogram
if ( (cmd | getline line) > 0 ) {
$col = line
}
close(cmd)
}
{ print }
$ awk -v myprogram='tr [:lower:] [:upper:]' -v col=2 -f tst.awk file
column1 column2 column3 column4
text1.1 TEXT1.2 text1.3 text1.4
text2.2 TEXT2.2 text2.3 text3.4
$ awk -v myprogram='wc -c' -v col=2 -f tst.awk file
column1 column2 column3 column4
text1.1        9 text1.3 text1.4
text2.2        9 text2.3 text3.4
$ awk -v myprogram="sed 's/x/X/' | tr 't' '#'" -v col=3 -f tst.awk file
column1 column2 column3 column4
text1.1 text1.2 #eX#1.3 text1.4
text2.2 text2.2 #eX#2.3 text3.4

使用awk,您可以简单地将前缀连接到第二个字段,例如

awk 'FNR > 1 && NF > 1 {$2="transformed-"$2}1' file

它只检查行中是否至少有2个字段,然后设置前缀"transformed-",然后从文件的第二行连接到行中的第二个字段,直到结束。

示例使用/输出

使用一个简单的heredocawk提供输入,您可以执行以下操作:

$ cat << eof | awk 'FNR > 1 && NF > 1 {$2="transformed-"$2}1'
> column1 column2 column3 column4
> text1.1 text1.2 text1.3 text1.4
> text2.2 text2.2 text2.3 text3.4
> eof
column1 column2 column3 column4
text1.1 transformed-text1.2 text1.3 text1.4
text2.2 transformed-text2.2 text2.3 text3.4

这里有一种丑陋的方法,只需使用sed对列2:进行简单转换

paste <(cut -f1 -d' ' file) <(cut -f2 -d' ' file | sed 's/text/TEXT/') <(cut -f3,4 -d' ' file)

输出

text1.1 TEXT1.2 text1.3 text1.4
text2.2 TEXT2.2 text2.3 text3.4

它本质上是将3个文件并排粘贴在一起,所以读起来是:

paste file1 file2 file3

其中,file1是从输入文件中剪切第一个字段时得到的结果,file2是剪切和转换输入文件的第二个字段时获得的结果,而file3是从输入文档中剪切字段3和4时得到的值。


或普通bash:

#!/bin/bash
while read c1 c2 rest ; do
c2trans=$(echo "$c2" | ./transformer)
echo "$c1 $c2trans $rest"
done < file

最新更新