只打印超过 $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 循环。
我只想打印包含 $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 循环。