是否可以将awk中的print语句传递给多个文本文件?

时间:2014-07-24 15:42:48

标签: linux bash shell awk scripting

我认为这个问题不言而喻。我有两个文本文件:file1和file2。以下是bash脚本中包含awk的示例代码:

编辑:我正在使用gnu awk

我的剧本:

val=3

awk 'if ("'$val'" == "3")
         print "Hello" >> "'$PWD/file1.txt'"
     else 
         print "Goodbye" #append to file1.txt and file2.txt
     '

我不想要这样的事情:     VAL = 3

awk 'if ("'$val'" == "3")
         print "Hello" >> "'$PWD/file1.txt'"
     else {
         print "Goodbye" >> "'$PWD/file1.txt'" 
         print "Goodbye" >> "'$PWD/file2.txt'"
     }'

我知道在bash中你可以使用tee来管道传输多个文件。可以在gnu awk中使用吗?如果是这样呢?在gnu awk中有另一种方法吗?

2 个答案:

答案 0 :(得分:2)

GNU Awk 手册显示了how to simulate tee with awk的示例。这可能是一个很好的起点。

基本思想是将各种输出文件名存储在一个数组中 - 然后循环遍历此数组,以便依次发送每个文件的输出。在你的情况下之类的东西(我直接在SO中输入 - 你必须根据你的需要调整/修复):

BEGIN {
  output[0] = "'$PWD/file1.txt'" 
  output[1] = "'$PWD/file1.txt'" 
  ...
}

{
    for (i in output)
        print "Goodbye!" >> output[i]
}

  

我知道在bash中你可以使用tee来管道到多个文件。可以在gnu awk中使用吗?

如果只有非awk解决方案可以接受,另一个选项是将一些filedescriptor重定向到外部bash脚本中的tee,然后将输出发送到{{> fd 来自{{ 1}}需要时。这是一个简单的例子:

awk

产生:

#!/bin/bash

exec 4<> >(tee file1.txt file2.txt)

awk '{ print NR;                        # send only to stdout
       print "READ:" $0 >> "/dev/fd/4"; # send to `tee`
}'

答案 1 :(得分:1)

你的awk脚本在访问shell变量值的方式上是错误的,并且你将整个脚本放在条件部分中,因此如果没有语法错误会产生不良副作用。

你的剧本:

val=3
awk 'if ("'$val'" == "3")
         print "Hello" >> "'$PWD/file1.txt'"
     else 
         print "Goodbye" #append to file1.txt and file2.txt
     '

应该写成:

val=3
awk -v val="$val" -v pwd="${PWD}/" '{
     if (val == 3)
         print "Hello" >> (pwd "file1.txt")
     else 
         print "Goodbye" #append to file1.txt and file2.txt
}'

在语法上是正确的。要将其展开以打印到多个文件是:

val=3
awk -v val="$val" -v pwd="${PWD}/" '{
     if (val == 3) {
         print "Hello" >> (pwd "file1.txt")
     }
     else {
         print "Goodbye" >> (pwd "file1.txt")
         print "Goodbye" >> (pwd "file2.txt")
     }
}'

或者:

val=3
awk -v val="$val" -v pwd="${PWD}/" '
BEGIN { split("file1 file2",files) }
{
     if (val == 3)
         print "Hello" >> (pwd "file1.txt")
     else
         for (f in files)
             print "Goodbye" >> (pwd files[f] ".txt")
}'