我有一个包含以下内容的文本:
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%sn 47, 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%sn 47, 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-"
,然后从文件的第二行连接到行中的第二个字段,直到结束。
示例使用/输出
使用一个简单的heredoc为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
这里有一种丑陋的方法,只需使用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