【问题标题】:Which parameter is pipe mapped to in bash or shell?在 bash 或 shell 中管道映射到哪个参数?
【发布时间】:2016-02-10 21:27:03
【问题描述】:

我有一个脚本,可以格式化一些难以阅读的日志文件的输出,以使它们易于阅读。我按如下方式调用我的脚本

me@myHost $ cat superBigLogFile$date | grep "Stuff from log file I want to see" | /scripts/logFileFormatter

在脚本内部,它使用了 $0、$1 和 $2,但我不知道 cat'ed 文本映射到哪个参数。我想对脚本进行更改,我只需要输入日期和我想看到的内容。如:

me@myHost $/scripts/logFileFormatter 2016-02-10 "Stuff I want to see"

以下是脚本的详细信息。技术细节是该脚本将 NDM 日志的输出格​​式化为人类可读的形式。

PATH=/usr/xpg4/bin:/usr/bin
# add SUMM field and end of record marker on stat lines
awk '{print $0"|SUMM=N|EOR"}' |\
# format the STAT file, putting each field on a separate line
tr '|' '\012' |\
# separate times from dates and reformat source and destination file fields
# to have a space after the =
awk -F= '{
    if ($1=="DFIL" || $1=="SFIL") print $1 "= " $2
    else if ($1=="STAR" || $1=="SSTA" || $1=="STOP" ) {
      split($2,A," ")
      print $1 "=" A[1] "=" A[2]
    }
    else print
}' |\
# execute the ndmstat.awk that comes with Connect:Direct
awk -F= -f /cdndm/cmddbp1/cdunix/ndm/bin/ndmstat.awk |\
# additional formatting to remove the greater than sign arrows
sed 's/=>/=/g'

【问题讨论】:

  • $0, $1, 等等...不是外壳。那是awk
  • 不是参数。这是标准输入。
  • 这个问题所基于的前提是非常错误的,我不确定它可以简洁地回答。

标签: bash shell pipe sh


【解决方案1】:

管道 - | - 获取一个命令的标准输出并将其“连接”到另一个命令的标准输入。

一个简单的脚本(假设它被称为script.sh):

while read line
do
        echo "line" $line
done

可以这样工作:

$ ls -al | ./script.sh
line total 15752
line drwxr-xr-x+ 106 kls staff 3604 Feb 10 23:13 .
line drwxr-xr-x 6 root admin 204 May 23 2015 ..
line -rwxr-xr-x 1 kls staff 56 Feb 10 23:13 a.sh

这里的关键部分是一个read 命令,它从标准输入读取并将结果逐行放入line 变量中。这样每行都会在循环中打印(在上面的示例中,它还以“行”字为前缀,以区别于常规的 ls -al 输出)。

现在,我没有测试数据来运行您的脚本,但它与 awk 非常相似。考虑这个脚本(保存到script.sh):

awk '{print $1}'

可以像这样调用:

$ ls -al | ./script.sh
total
drwxr-xr-x+
drwxr-xr-x
-rwxr-xr-x

这表明 awk 确实在做它的工作 - 它会获取并打印由 ls -al 生成的输出的每一行的第一个令牌 ($1)(通过标准输入 - |)。


注意 Bash 和 Awk 中的 $1

重要提示:$1 这里不是 Bash 变量 - 它是在 awk 中定义的变量。它并不像在 Bash 中那样表示“脚本的第一个参数”,而是“输入中的第一个标记”。这两者是完全独立的——这显示了如何同时使用它们:

script.sh:

awk "{print \"$1 \" \$1}"
              ^       ^
              |       |
            Bash     Awk

输出:

$ ls -al | ./script.sh PREFIX       <-- We pass PREFIX now that
                                        will be bound to $1 Bash variable.
PREFIX total
PREFIX drwxr-xr-x+
PREFIX drwxr-xr-x
PREFIX -rwxr-xr-x

一开始可能有点奇怪,所以我在代码中添加了一些 cmets。仔细检查双引号,以及它们是如何用\ 符号转义的。相似地。 awk $1 也被转义(\$1),而 Bash 则没有。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-07
    • 2020-05-26
    • 1970-01-01
    • 1970-01-01
    • 2019-07-26
    • 2021-03-09
    相关资源
    最近更新 更多