只打印超过 $1 个字的行

Print only lines with more than $1 words

我只想打印包含 $1 个或更多字数的行。请帮忙。

while read line ; do
    echo $line | wc -w 
done t1.txt

假设您将一个单词定义为由 space 分隔的字符,那么 awk 将很容易做到这一点:

awk -v COUNT= 'NF>COUNT' t1.txt

它将第一个参数作为名为 count 的 awk 变量传递,并打印 space 分隔字段的数量超过提供的计数的行。

例如

$ echo $COUNT
3
$ cat t1.txt
hey
hey hey hey hey hey
hey hey hey
hey hey hey
hey hey hey hey hey
hey hey hey hey hey
hey hey hey

$ awk -v COUNT=$COUNT 'NF>COUNT' t1.txt
hey hey hey hey hey
hey hey hey hey hey
hey hey hey hey hey

使用 while 构造时要记住两件事。
1. 使用 read -r,而不是 read 来保证你输入的字面意义。 2. 将外部命令置于 body 之外(就像现在一样)。 当您想使用 while 和外部实用程序处理行时,请尝试将外部实用程序拉到 while 循环之外。在 while 循环中它会被每一行调用,在循环外它只会被调用一次。 您可能希望将预处理命令链放在 while 循环之前:

cmd1 | cmd2 | cmd3 | while read -r line; do
   echo "This ${line} has been preprocessed."
done

这个解决方案有一个很大的缺点。 while-loop 在子流程中处理,对循环中设置的变量所做的任何更改都将丢失。

您可以通过 "process substitution" 改进:

while read -r line; do
   echo "This ${line} has been preprocessed."
done < <(cmd1 | cmd2 | cmd3)

现在让我们关注cmd1 | cmd2 | cmd3。如何从每行中获取 ${n} 个单词的前 3 个?您需要根据您希望如何查看单词来调整您的命令。 word<space><space>word 是2个字的一行,还是第二个和第三个字为空的一行? 使用不同的选项来解析 t1.txt:

awk # syntax not included here
grep ".* .* .*" # Difficult to use $n
grep -E "^(\w+ *){3,}" t1.txt
grep -E "^(\w+ *){$n,}" t1.txt
sed -n '/.* .* .*/p' t1.txt

这些命令的输出可以重定向到 while 循环,但对于您的基本要求,可以跳过 while 循环。