如何在bash awk中对文本中的一列应用程序?

问题描述 投票:0回答:2

我有一个文本,其中包含这样的内容,我想执行一个程序,将第2列中的所有文本转换为新的文本。

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是一种方式,但我对它不够了解。

谅谅

bash awk
2个回答
2
投票
$ cat tst.awk
BEGIN { myprogram = "tr [:lower:] [:upper:]" }
NR>1 {
    cmd = "printf \047%s\n\047, \047" $2 "\047 | " 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 \047%s\n\047, \047" $col "\047 | " 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

1
投票

有了 awk 你可以简单地将前缀连接到第二个字段上,如

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

这只是检查你的行中是否至少有两个字段,然后设置并连接前缀。"transformed-" 到该行的第二个字段,从文件的第二行开始直到最后。

例子 UseOutput

使用简单的 遗传性 以提供输入到 awk 你可以做。

$ 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

1
投票

这里有一个丑陋的方法,只是用... 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
© www.soinside.com 2019 - 2024. All rights reserved.