是否可以在管道中设置变量?

时间:2016-05-03 13:17:16

标签: bash variables pipeline

我有一个很大的txt文件,我想在管道中编辑。但是在管道中的同一个地方我想设置变量$ nol中的行数。我只是想看看sintax如何在管道中设置变量,如:

  cat ${!#} | tr ' ' '\n'| grep . ; $nol=wc -l | sort | uniq -c ...

在第二个管道之后是非常错误的,但我怎么能在bash中做到这一点?

其中一个解决方案是:

nol=$(cat ${!#} | tr ' ' '\n'| grep . | wc -l)
pipeline all from the start again

但我不想两次做同样的事情,因为我在这里有更多的管道。

我不使用awk或sed ......

4 个答案:

答案 0 :(得分:1)

您可以在管道的特定链接中设置变量,但这不是非常有用,因为只有该特定链接会受其影响。

我建议只使用临时文件。

set -e
trap 'rm -f "$tmpf"' EXIT
tmpf=`mktemp`
cat ${!#} | tr ' ' '\n'| grep . | sort > "$tmpf"
nol="$(wc "$tmpf")"
< "$tmpf" uniq -c ...

你可以避免使用tee和命名管道的临时文件,但它可能不会表现得更好(甚至可能表现更差)。

答案 1 :(得分:1)

在我看来,你问的是如何避免两次单步执行文件,只是为了得到单词和行数。

Bash可让您阅读变量, $collection = Yii::$app->mongodb->getCollection('your_mongo_collection'); $data = $collection->aggregate( [ '$match' => [ 'name' => $name, ] ], [ '$group' => [ '_id' => '_id', 'count' => [ '$sum' => 1 ] ] ] ); 可以一次生成所需的所有数字。

wc

首先......

NAME
     wc -- word, line, character, and byte count

这将根据process substitution生成的输入填充三个变量。

但是你的问题还包括另一个我认为你想要的部分命令行:

read words line chars < <( wc < ${!#} )

这与您的第一个命令行的字数显着不同,因此您不能使用单个nol=$( sort -u ${!#} | wc -l ) 实例来生成两者。相反,一个选项可能是将您的功能放入一次执行这两个功能的脚本中:

wc

答案 2 :(得分:1)

您可以使用tee,然后将其写入稍后使用的文件:

tempfile="xyz"
tr ' ' '\n' < "${!#}" | grep '.' | tee > "$tempfile" | sort | uniq -c ...
nol=$(wc -l "$tempfile")

或者您可以反过来使用它:

nol=$(tr ' ' '\n' < "${!#}" | grep '.' \
  | tee >(sort | uniq -c ... > /dev/tty) | wc -l

答案 3 :(得分:1)

<强>更新

花了一分钟,但我明白了......

cat ${!#} | tr ' ' '\n'| tee >(nol=$(wc -l)) | sort | uniq -c ...

<强> PREVIOUS:

我能想到的唯一方法是存储变量并回调。您不会多次执行该命令。您只需将输出存储在变量中。

aCommand=($(cat ${!#} | tr ' ' '\n'));sLineCount=$(echo ${#aCommand[@]});echo ${aCommand[@]} | sort | uniq -c ...
  • aCommand会将第一组命令的结果存储在数组
  • sLineCount将计算数组中的元素(行)
  • ; ...回显数组元素并从那里继续执行命令。