在 linux 的文本文件中打印单词(即 7 个字母)
Print words(that are 7 letters) in a text file in linux
我的文件中 7 个字母的单词代码:
cat file.txt | tr -cs "[:alnum:]" "\n"| tr "[:lower:]" "[:upper:]" | awk '{h[]++}END{for (i in h){print h[i]" "i}}'| grep -w "\w\{7\}" -w | sort -nr | cat -n | head -n 5
这是输出:this picture shows the top 5 words written
这是文件 link: https://www.gutenberg.org/cache/epub/996/file.txt
请您尝试以下操作:
tr [:lower:] [:upper:] < uly.txt | awk '
{
for (i=1; i<=NF; i++) {
sub(/[^[:alnum:]]+$/, "", $i)
if (length($i) >= 7) h[$i]++
}
}
END {
for (i in h) {print h[i]" "i}
}' | sort -nr | cat -n | head -n 5
输出:
1 3 QUIXOTE
2 3 PROJECT
3 3 GUTENBERG
4 2 LOCATED
5 2 HISTORY
如果您使用的是 GNU AWK
,您通常可以执行其他文本处理命令所执行的操作,我将从
开始介绍后续步骤
cat uly.txt | tr -cs "[:alnum:]" "\n"| tr "[:lower:]" "[:upper:]" | awk '{h[]++}END{for (i in h){print h[i]" "i}}'| grep -w "\w\{7\}" -w | sort -nr | cat -n | head -n 5
首先 GNU AWK
在 String Functions 中有 tolower
所以我们可以用它代替 tr
进行小写
cat uly.txt | tr -cs "[:alnum:]" "\n"| awk '{h[tolower()]++}END{for (i in h){print h[i]" "i}}'| grep -w "\w\{7\}" -w | sort -nr | cat -n | head -n 5
还有一个length
函数可以return个字符,所以我们可以用它来代替grep
如下
cat uly.txt | tr -cs "[:alnum:]" "\n"| awk 'length()==7{h[tolower()]++}END{for (i in h){print h[i]" "i}}'| sort -nr | cat -n | head -n 5
条件先于动作意味着我们只在满足条件时才执行动作,请注意,这也会导致内存使用量减少,因为不会保留不同长度单词的信息。
GNU AWK
能够以多种方式对数组进行排序,Using Predefined Array Scanning Orders with gawk
中对此进行了描述,因为您使用值来存储数字并希望按降序排列(最常见到最不常见),您应该使用@val_num_desc
。这允许替换 sort
cat uly.txt | tr -cs "[:alnum:]" "\n"| awk 'BEGIN{PROCINFO["sorted_in"]="@val_num_desc"}length()==7{h[tolower()]++}END{for (i in h){print h[i]" "i}}'| cat -n | head -n 5
在 for
循环中获取后续数字可以使用增量运算符之一完成,我会使用 increment-then-return (变量前加号)而不是 return-then-increment (变量后加号)作为您希望编号从 1 而不是 0 开始。这将用于代替 cat -n
即
cat uly.txt | tr -cs "[:alnum:]" "\n"| awk 'BEGIN{PROCINFO["sorted_in"]="@val_num_desc"}length()==7{h[tolower()]++}END{for (i in h){print ++j" "h[i]" "i}}'| head -n 5
我使用了 j
变量,因为它还没有被使用过。现在我们可以访问行数,很容易在输出 5 个单词后结束处理,这将替换 head -n 5
即
cat uly.txt | tr -cs "[:alnum:]" "\n"| awk 'BEGIN{PROCINFO["sorted_in"]="@val_num_desc"}length()==7{h[tolower()]++}END{for (i in h){print ++j" "h[i]" "i;if(j>=5){exit}}}'
Exit statement 允许您结束程序。如果您的文件很大,但只处理其中相对较小的一部分就可以得到所需的答案,这尤其方便。
我们可以通过提供行分隔符(RS
来告知GNU AWK
它应该考虑什么行,而不是使用tr
预处理文件) 在这种情况下
cat uly.txt | awk 'BEGIN{RS="[^[:alnum:]]+";PROCINFO["sorted_in"]="@val_num_desc"}length()==7{h[tolower()]++}END{for (i in h){print ++j" "h[i]" "i;if(j>=5){exit}}}'
[^[:alnum:]]+
意思是 1 个或多个 (+
) 除了 (^
) 个字母数字字符 ([:alnum:]
)。最后,GNU AWK
不限于使用标准输入 - 您可以使用参数来传递文件进行处理,因此我们可以使用它来替换 cat
以获取
awk 'BEGIN{RS="[^[:alnum:]]+";PROCINFO["sorted_in"]="@val_num_desc"}length()==7{h[tolower()]++}END{for (i in h){print ++j" "h[i]" "i;if(j>=5){exit}}}' uly.txt
请注意,将 cat
的管道输出传输到本身可以读取文件的工具中通常被认为是反模式,甚至有自己的名称:猫的无用使用
我的文件中 7 个字母的单词代码:
cat file.txt | tr -cs "[:alnum:]" "\n"| tr "[:lower:]" "[:upper:]" | awk '{h[]++}END{for (i in h){print h[i]" "i}}'| grep -w "\w\{7\}" -w | sort -nr | cat -n | head -n 5
这是输出:this picture shows the top 5 words written
这是文件 link: https://www.gutenberg.org/cache/epub/996/file.txt
请您尝试以下操作:
tr [:lower:] [:upper:] < uly.txt | awk '
{
for (i=1; i<=NF; i++) {
sub(/[^[:alnum:]]+$/, "", $i)
if (length($i) >= 7) h[$i]++
}
}
END {
for (i in h) {print h[i]" "i}
}' | sort -nr | cat -n | head -n 5
输出:
1 3 QUIXOTE
2 3 PROJECT
3 3 GUTENBERG
4 2 LOCATED
5 2 HISTORY
如果您使用的是 GNU AWK
,您通常可以执行其他文本处理命令所执行的操作,我将从
cat uly.txt | tr -cs "[:alnum:]" "\n"| tr "[:lower:]" "[:upper:]" | awk '{h[]++}END{for (i in h){print h[i]" "i}}'| grep -w "\w\{7\}" -w | sort -nr | cat -n | head -n 5
首先 GNU AWK
在 String Functions 中有 tolower
所以我们可以用它代替 tr
进行小写
cat uly.txt | tr -cs "[:alnum:]" "\n"| awk '{h[tolower()]++}END{for (i in h){print h[i]" "i}}'| grep -w "\w\{7\}" -w | sort -nr | cat -n | head -n 5
还有一个length
函数可以return个字符,所以我们可以用它来代替grep
如下
cat uly.txt | tr -cs "[:alnum:]" "\n"| awk 'length()==7{h[tolower()]++}END{for (i in h){print h[i]" "i}}'| sort -nr | cat -n | head -n 5
条件先于动作意味着我们只在满足条件时才执行动作,请注意,这也会导致内存使用量减少,因为不会保留不同长度单词的信息。
GNU AWK
能够以多种方式对数组进行排序,Using Predefined Array Scanning Orders with gawk
中对此进行了描述,因为您使用值来存储数字并希望按降序排列(最常见到最不常见),您应该使用@val_num_desc
。这允许替换 sort
cat uly.txt | tr -cs "[:alnum:]" "\n"| awk 'BEGIN{PROCINFO["sorted_in"]="@val_num_desc"}length()==7{h[tolower()]++}END{for (i in h){print h[i]" "i}}'| cat -n | head -n 5
在 for
循环中获取后续数字可以使用增量运算符之一完成,我会使用 increment-then-return (变量前加号)而不是 return-then-increment (变量后加号)作为您希望编号从 1 而不是 0 开始。这将用于代替 cat -n
即
cat uly.txt | tr -cs "[:alnum:]" "\n"| awk 'BEGIN{PROCINFO["sorted_in"]="@val_num_desc"}length()==7{h[tolower()]++}END{for (i in h){print ++j" "h[i]" "i}}'| head -n 5
我使用了 j
变量,因为它还没有被使用过。现在我们可以访问行数,很容易在输出 5 个单词后结束处理,这将替换 head -n 5
即
cat uly.txt | tr -cs "[:alnum:]" "\n"| awk 'BEGIN{PROCINFO["sorted_in"]="@val_num_desc"}length()==7{h[tolower()]++}END{for (i in h){print ++j" "h[i]" "i;if(j>=5){exit}}}'
Exit statement 允许您结束程序。如果您的文件很大,但只处理其中相对较小的一部分就可以得到所需的答案,这尤其方便。
我们可以通过提供行分隔符(RS
来告知GNU AWK
它应该考虑什么行,而不是使用tr
预处理文件) 在这种情况下
cat uly.txt | awk 'BEGIN{RS="[^[:alnum:]]+";PROCINFO["sorted_in"]="@val_num_desc"}length()==7{h[tolower()]++}END{for (i in h){print ++j" "h[i]" "i;if(j>=5){exit}}}'
[^[:alnum:]]+
意思是 1 个或多个 (+
) 除了 (^
) 个字母数字字符 ([:alnum:]
)。最后,GNU AWK
不限于使用标准输入 - 您可以使用参数来传递文件进行处理,因此我们可以使用它来替换 cat
以获取
awk 'BEGIN{RS="[^[:alnum:]]+";PROCINFO["sorted_in"]="@val_num_desc"}length()==7{h[tolower()]++}END{for (i in h){print ++j" "h[i]" "i;if(j>=5){exit}}}' uly.txt
请注意,将 cat
的管道输出传输到本身可以读取文件的工具中通常被认为是反模式,甚至有自己的名称:猫的无用使用