【问题标题】:Is it possible to pipe a print statement in awk to multiple text files?是否可以将 awk 中的打印语句通过管道传输到多个文本文件?
【发布时间】:2014-07-24 15:42:48
【问题描述】:

我认为这个问题不言自明。我有两个文本文件: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 中还有其他方法吗?

【问题讨论】:

  • 你的 awk 风格是什么? GNU awk,或 nawk,或 ...
  • @SylvainLeroux GNU Awk

标签: linux bash shell awk scripting


【解决方案1】:

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 的解决方案,另一种选择是将某些文件描述符重定向到外部 bash 脚本中的 tee,然后从 awk 将输出发送到该 fd必需的。这是一个简单的例子:

#!/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`
}'

产生:

sh$ (echo a; echo b) | ./a.sh
1
2
READ:a
READ:b
sh$ cat file1.txt 
READ:a
READ:b
sh$ cat file2.txt 
READ:a
READ:b

【讨论】:

  • 感谢您的课程! +1
【解决方案2】:

您的 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")
}'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 2014-08-17
    • 1970-01-01
    • 2019-01-24
    • 1970-01-01
    相关资源
    最近更新 更多