您可以使用 heredocuments 在 bash 脚本中嵌入 AWK 吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6489995/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 00:15:26  来源:igfitidea点击:

Can you use heredocuments to embed AWK in a bash script?

bashawk

提问by nperson325681

Writing a shell script that pretty much wraps around an Awk script. I'd like to have my syntax colouring on in the awk section so I feel there must be a better way to embed awk scripts to bash than just quote the script in.

编写一个几乎围绕 Awk 脚本的 shell 脚本。我想在 awk 部分使用我的语法着色,所以我觉得必须有更好的方法将 awk 脚本嵌入到 bash 中,而不仅仅是引用脚本。

Or is it the best way to develop the awk on a separate file and use awk -fin the bash script until the script's done? I'd like to keep within one file all times!

或者它是在单独的文件上开发 awk 并awk -f在 bash 脚本中使用直到脚本完成的最佳方法?我想一直保持在一个文件内!

#!/bin/bash
awkscript='
BEGIN{
    print "test"
}
{print }'
df | awk "$awkscript"

This is the quote way, and quite ugly if you ask me. Any chance for heredocs here?

这是引用方式,如果你问我的话,这很丑陋。这里有继承人的机会吗?

回答by mss

Yes, in Bash this is possible in a slightly less ugly way:

是的,在 Bash 中,这可以通过稍微不那么丑陋的方式实现:

#!/bin/bash
df | awk -f <(cat - <<-'EOD'
        BEGIN{
            print "test"
        }
        {print }
EOD
)

The <()code block is replaced with a path (something like /dev/fd/63) which points to a file descriptor tied to the output of the code. Make sure the awk script is indented with tabs and not spaces (<<-strips leading tabs).

<()代码块被替换的路径(像/dev/fd/63),它指向一个文件描述符绑在码的输出中。确保 awk 脚本使用制表符而不是空格(<<-去除前导制表符)缩进。

Another way to do this is to hide the awk script at the end of the bash script like this (don't forget to exit):

另一种方法是像这样隐藏 bash 脚本末尾的 awk 脚本(不要忘记exit):

#!/bin/bash
df | awk -f <(sed -e '0,/^#!.*awk/d' 
read -r -d '' awkscript <<'EOF'
BEGIN{ print "test"}
{print }
EOF
df | awk "$awkscript"
) exit $PIPESTATUS #!/usr/bin/awk -f BEGIN { print "test" } {print }

回答by jm666

ugly too:

也丑:

awk -f- inputfile.txt <<'EOF'
BEGIN {
  print "hello world"
}
EOF

回答by David Given

If you don't want to use stdin for the data, do this --- it's portable, fast, and doesn't use any bashisms.

如果您不想将 stdin 用于数据,请执行此操作 --- 它是可移植的、快速的,并且不使用任何 bashisms。

f=/tmp/$$.data
trap "rm -f $f" EXIT
mknod $f p
(df > $f) &
awk -f- $f <<EOF
{ print }
EOF

Telling awk to use an input filename of -causes it to read the script from stdin.

告诉 awk 使用输入文件名-导致它从标准输入读取脚本。

Of course, you now have to store your data in a file. If you reallycan't do this, use a named pipe.

当然,您现在必须将数据存储在文件中。如果您实在无法做到这一点,请使用命名管道。

#!/bin/bash

awk 'BEGIN {
    print "hello world"
}
{ 
    print 
}' <<< "$(df)"

回答by Fredrik Pihl

Not sure what you mean, but are you looking for something like this?

不确定你的意思,但你在寻找这样的东西吗?

awkscript=$(cat << EOT
BEGIN{
    print "test"
}
{print }
EOT
)

df | awk "$awkscript"

Have a look at 3.6.7 Here Stringsin the bash manual

看看bash 手册中的3.6.7 Here Strings

回答by Sylvain Leroux

Sometimes this may be usefull:

有时这可能很有用:

awk -f- <(df) <<'EOF'
BEGIN{
    print "test"
}
{print }
EOF

回答by Liu Sha

One way is to let awk read rules from stdin using (heredoc or here string) but process real files or files created by subprocess substitution, like this

一种方法是让 awk 使用 (heredoc or here string) 从 stdin 读取规则,但处理真实文件或由子进程替换创建的文件,如下所示

##代码##

-f-should appear before <(df). The delimiter for the heredoc should be quoted so that the $signs will be passed into awk instead of being expanded.

-f-应该出现在<(df). 应该引用 heredoc 的分隔符,以便将$符号传递到 awk 而不是被扩展。