【发布时间】:2021-11-19 04:25:29
【问题描述】:
我正在尝试计算一个非常大的文件中的行匹配数,并仅使用 BASH shell 命令将它们存储在变量中。
目前,我正在扫描一个非常大的文件的结果两次,并且每次都使用单独的 grep 语句,如下所示:
$ cat test.txt
first example line one
first example line two
first example line three
second example line one
second example line two
$ FIRST=$( cat test.txt | grep 'first example' | wc --lines ; ) ; ## first run
$ SECOND=$(cat test.txt | grep 'second example' | wc --lines ; ) ; ## second run
我最终得到了这个:
$ echo $FIRST
3
$ echo $SECOND
2
希望,我只想扫描一次大文件。而且我从来没有使用过 Awk 并且宁愿不使用它!
|tee 选项对我来说是新的。似乎将结果传递给两个单独的 grep 语句可能意味着我们只需要扫描一次大文件。
理想情况下,我也希望能够做到这一点,而不必创建任何临时文件,并且随后必须记住删除它们。
我尝试了多种方法,如下所示:
FIRST=''; SECOND='';
cat test.txt \
|tee >(FIRST=$( grep 'first example' | wc --lines ;);) \
>(SECOND=$(grep 'second example' | wc --lines ;);) \
>/dev/null ;
并使用read:
FIRST=''; SECOND='';
cat test.txt \
|tee >(grep 'first example' | wc --lines | (read FIRST); ); \
>(grep 'second example' | wc --lines | (read SECOND); ); \
> /dev/null ;
cat test.txt \
| tee <( read FIRST < <(grep 'first example' | wc --lines )) \
<( read SECOND < <(grep 'sedond example' | wc --lines )) \
> /dev/null ;
并带有大括号:
FIRST=''; SECOND='';
cat test.txt \
|tee >(FIRST={$( grep 'first example' | wc --lines ;)} ) \
>(SECOND={$(grep 'second example' | wc --lines ;)} ) \
>/dev/null ;
但这些都不允许我将行数保存到变量 FIRST 和 SECOND 中。 p>
这有可能吗?
【问题讨论】:
-
"$( cat test.txt | grep 'first example' | wc --lines ; )" 你不需要 cat,只需要 "grep 'first example' test.txt" 你会避免额外的过程
-
你会找到答案here。
-
为什么不喜欢使用
awk?使用一个相对简单的awk脚本,您可以替换所有当前代码并且只扫描文件一次 -
>(command)进程替换在子 shell 中运行命令。您在子 shell 中设置的变量不会保留在运行脚本的父 shell 中。抱歉,这种方法无法如您所愿。 -
@edwardsmarkf :
tee不是一个选项,它是一个可执行命令 - 参见 man tee。