35

我有一个这样定义的 awk 脚本:

#!/usr/bin/env awk
BEGIN { if (!len) len = 1; end = start + len }
{ for (i = start; i < end; i++) { print $1 } }

我已将其保存为columns并保存了chmod +x它。我想调用它,以便在它遍历文件时定义它startend我在想这应该可行:

cat some_file | columns -v start=2

但事实并非如此。帮助!

4

4 回答 4

61

尝试使用:

#!/usr/bin/awk -f

作为翻译

于 2009-09-13T17:22:04.407 回答
12

env 是处理此问题的最简单方法:

#!/usr/bin/env -S awk -f

添加更多选项,并确保不会干扰您的论点和 awk 的论点:

#!/usr/bin/env -S awk -F: -f ${_} --
BEGIN {
    # delete argv[1], which == ENVIRON[_]
    delete ARGV[1]
} # rest of my awk program

由于 env 有一个 POSIX 标准,这个 shbang 应该可以帮助您解决跨 unixen 的非标准 shbang 实现的困难。

编辑

在写完这篇文章后,我意识到'-S' 是一个不符合 POSIX 的 FreeBSD env 扩展。所以外壳包装器可能是要走的路,不幸的是。

于 2011-08-08T03:36:51.520 回答
3

不幸的是,这并不容易以便携的方式解决。标准技术如下所示(代替/usr/bin/awk您的 awk 路径):

#!/usr/bin/awk -f

BEGIN { if (!len) len = 1; end = start + len }
{ for (i = start; i < end; i++) { print $1 } }

硬编码的awk路径和非标准-f标志,使得它不能在所有 *nixes 中移植。如果您只打算在一台机器上运行您的脚本,那么这可能工作正常。但是,要制作可移植awk脚本,您需要将其包装在 shell 脚本中。以下是您可以在一个文件中执行此操作的两种方法:

第一种方式是标准且易于阅读的:

#!/bin/sh

awk '
BEGIN { if (!len) len = 1; end = start + len }
{ for (i = start; i < end; i++) { print $1 } }
' "$@"

不幸的是,这在两个关键方面有所不足:

  1. 如果您的 awk 脚本包含一个'字符,您需要像这样键入它:'"'"'“转义”它。
  2. 如果您使用带有语法突出显示的文本编辑器,您将无法正确突出显示您的 awk 脚本。

另一种解决方案是使用sed剥离sh包装器:

#!/bin/sh
exec awk "$(sed '1,2d' "$0")" "$@"

BEGIN { if (!len) len = 1; end = start + len }
{ for (i = start; i < end; i++) { print $1 } }

这有点像两行 shabang 标题。它使用第 3 行以下的文件作为脚本参数调用 awk。这使您可以保持漂亮的语法突出显示,并且您仍然可以随心所欲'地使用字符。我看到的两个缺点是:

  1. 可以说这是不直观的阅读。
  2. 如果您使用的是代码 linter,它可能不会这样。
于 2019-12-13T21:50:12.343 回答
0

下面是这个问题的答案——

#!/bin/awk -f 
于 2016-10-05T11:01:14.927 回答