如果bash命令接受文件名作为最后一个arg,可以使用管道提供文件内容吗?

时间:2019-05-29 05:17:52

标签: bash

说一个命令将文件名作为其最后一个参数:

count-words "$word" file.txt

是否有一种使用管道提供文件内容而不是写入临时文件的方法?

4 个答案:

答案 0 :(得分:2)

每个参数(无论位置如何)都是一个字符串,程序在bash执行之后会自行处理。 bash无法干预。

单个程序可能会提供从标准输入中读取的选项,或者默认情况下会这样做,但是,如果程序不这样做,则需要将其指向文件系统上的文件。

答案 1 :(得分:2)

我不确定我是否正确理解了您的要求,但您可能会 处于以下情况:

  • 您有一个打印文本的程序(例如“生成单词”) 到stdout
  • 您还有一个程序“ count-words”,用于计算给定单词 在指定的文本文件中。
  • 您可以通过编写“ generate-words”的输出来组合两个程序 到临时文件file.txt
  • 但是您想找到一种解决方案而不写入临时文件。

如果以上假设正确,请尝试:

count-words "$word" <(generate-words)

其中<(command)被称为process substitution,您可以连接 command的输出(stdout)到其他需要文件名的程序 作为输入。

答案 2 :(得分:1)

许多程序将接受单个连字符(-)作为使用标准输入的指令。考虑到您如何调用示例命令,请考虑以下内容:

cat file.txt | grep -Fow "$word" - | wc -l

这将计算给定文件中$word的实例。 -F选项通过禁用正则表达式来加快搜索速度(因此.实际上意味着.),-o将输出设置为仅显示匹配项(每行一个),并且-w选项在单词的两边都需要单词边界(因此foofood匹配;请删除该标志以进行更改)。 wc -l将为您提供grep输出的行数,即$word的实例数。 (我没有使用grep -c,因为这会计数匹配的行,这意味着一行上的foo bar foo baz只会被计数一次。)


如果count-words是您的脚本,请考虑以下选项之一:

# imply standard input when given insufficient arguments
# or when the only argument is a hyphen
# (requires you to `shift` your options and the query term)
if [ "$#" = "0" ] || [ "$*" = "-" ]; then
  set -- /dev/stdin
fi

# convert hyphen(s) to /dev/stdin within the argument list
FIRST=1
for OPT in "$@"; do
  if [ "$FIRST" = 1 ]; then
    unset FIRST
    set --
  fi
  if [ "$OPT" = "-" ]; then
    OPT="/dev/stdin"
  fi
  set -- "$@" "$OPT"
done

这将使您能够以任何方式运行

  • count-words "$word" < file.txt
  • get-input | count-words "$word"
  • get-input | count-words "$word" -
  • get-input | count-words "$word" /dev/stdin
  • echo "$(get-input)" | count-words "$word"
  • count-words "$word" <<<"list of words as if echoed"
  • count-words "$word" <(get-input)

后三个是Bashisms,在dash或其他更简单的/bin/sh程序中不起作用。最后一条命令告诉count-words使用process substitution提供命名管道作为存储get-input输出的临时文件句柄。

答案 3 :(得分:0)

正如戈登·戴维森(Gordon Davisson)在评论中提到的那样,您可以使用代表标准输入的特殊文件/dev/stdin

some-command | count-words "$word" /dev/stdin