2016-06-09 104 views
0

这实际上就是我想要的命令,除了我想在第三列中打印使用shell命令的特殊东西(或者更多awk命令我猜,但我不知道我会如何适应原来的awk语句)。我需要帮助的是print命令中$ 2和ar [$ 4,$ 1]之间的伪命令替换,但为了特殊性而将剩下的部分留下。在必须访问awk命令的awk脚本中使用shell命令

awk 'NR==FNR{ar[$3,$2]=$1+ar[$3,$2]; } 
    NR>FNR && ar[$4,$1] {print "hs"$1,$2,`awk '$1 == #$1 from outer awk command# file2 | tail -n 1 | awk '{print $3}'`, ar[$4,$1]}' file1 file2 

文件1的样子

5 8  t11 
15 7  t12 
3 7  t14 

文件2的样子

8 4520 5560 t11 
8 5560 6610 t12 
8 6610 7400 t13 
7 9350 10610 t11 
7 10610 11770 t12 
7 11770 14627 t13 
7 14627 16789 t14 

和输出应该像

8 4520 7400 5 
7 10610 16789 15 
7 14647 16789 3 

的感谢!

+2

你在考虑这个错误。 Awk是一个操纵文本的工具。它不是调用工具(包括其他awk实例)的环境 - 这就是shell的用途。 [编辑]你的问题描述你想对你的输入做什么来创建你的输出(而不是**你认为你需要做什么),所以我们可以帮助你。 –

+0

我不明白'ar [$ 4,$ 1]'可以如何返回示例输出最后一列的值。对于这个问题,我没有看到输入中的任何内容可能会产生'5'和'15'的值。所以,正如EdM所说,让我们看看关于如何处理数据的一些规则。您几乎可以肯定地在awk中实现您的所需结果,或者重构您的shell代码以及它如何调用awk。 **请更新您的Q **。祝你好运。 – shellter

+1

@shelter,'5'和'15'来自_file1_。 – agc

回答

2

AWK,低效壳工具代码:

while read a b c ; do \ 
    echo -n "$b " ; \ 
    egrep "^$b " file2 | \ 
     grep -A 9999999 " $c" | \ 
     cut -d' ' -f2,3 | \ 
     sed '1{s/ .*//;t} 
      ${s/.* //;t};d' | \ 
     xargs echo -n ; \ 
    echo " $a" ; \ 
done < file1 | \ 
    column -t 

输出:

8 4520 7400 5 
7 10610 16789 15 

主循环输入file1的控制什么在file2中需要被打印。 文件1有领域,所以read需要3个变量:$一个$ B,并$ C。输出采用$ B$一个,所以这两个变量来“免费” - 主循环的第一个和最后一个行,(两者echo小号),前缀$ B和后缀$ a到每行中间的两个数字。

egrep打印文件2线与$ B开始,但这些线路,我们只想要$ C结束一加后,该线,这是什么打印出grep -A ...。只需要中间两列,所以cut只打印这些列。现在我们有一个两列数字块,我们只想要sed代码打印的左上角或右下角...

任何sed代码在运行时自动计算行数。当sed遇到第一行行时,它会运行第一组大括号中的内容('1{<代码>}')。如果失败sed检查它是否在最后线($意味着最后一行),如果sed运行什么是在第二组大括号,('${<代码>}')。如果不是第一行或最后一行sed将其删除。

里面那些大括号:s/ .*//就像cut -f 1会。关闭t意味着'GOTO标签',但是当没有'标签'sed刚刚开始一个新的循环时,读取另一行 - 没有t,代码将运行d,并且什么都不打印。随着两个领域,s/.* //作品像cut -f 2

主要while每次循环都sed打印号码,但每个都在它自己的路线。对xargs echo -n进行配管将两个数字放在同一行上,因为打印了$ b

+0

谢谢你,我意识到我输入了一个我的输入文件错误,但它应该在第3列t12而不是t11开始于7,以便输出10610在第二列第二行(那部分在那里)你知道如何相应地调整这个代码 – Jacob

+0

当我运行这个时,我得到了sed:1:“1 {s /。* // ; t}; $ {s /.* //; ...“:意外的EOF(正在执行)'),并且我不太熟悉sed – Jacob

+0

复制整个块,然后将其__立刻粘贴到命令行,它应该工作。 – agc