Shell 使用SED/AWK,从文本文件中提取行,其中行与前一行有N个常用词
下面是一个示例文本文件:Shell 使用SED/AWK,从文本文件中提取行,其中行与前一行有N个常用词,shell,awk,sed,Shell,Awk,Sed,下面是一个示例文本文件: word1 word2 word3 word4 word4 word5 word6 word7 word6 word7 word8 word9 word9 word6 word8 word3 word1 word4 word5 word4 用什么命令来提取前一行有N个常用词的行 在示例文件中,使用前一行中的3个常见不同单词提取行将输出: word9 word6 word8 word3 注意:使用编程语言extract array\u sentence1.uniq和a
word1 word2 word3 word4
word4 word5 word6 word7
word6 word7 word8 word9
word9 word6 word8 word3
word1 word4 word5 word4
用什么命令来提取前一行有N个常用词的行
在示例文件中,使用前一行中的3个常见不同单词提取行将输出:
word9 word6 word8 word3
注意:使用编程语言extract array\u sentence1.uniq和array\u sentence2.uniq很容易做到这一点,但我使用sed/awk搜索解决方案。以下是awk中的解决方案: ▶ cat>文件=3打印。。。然后打印这张唱片 如果发现3个或更多。 } { 最后=所有行上的0美元。 } 为了处理唯一性,我有一个修改过的解决方案,它使用GNU AWK的长度函数,同样在Mac OS X上的nawk中: script.gawk NR>1{ 最后,最后 分摊0美元,现钞 删除找到的计数有多少个唯一的事件 因为我现在看到的是文字。 最后一天的j 如果last_ar[j]==curr_ar[i] 找到[curr_ar[i]]++ 如果发现长度>=3,则打印 } { 最后=0美元 } 测试: ▶ gawk-f script.gawk文件 单词9单词6单词8单词3
以下是AWK中的一个解决方案: ▶ cat>文件=3打印。。。然后打印这张唱片 如果发现3个或更多。 } { 最后=所有行上的0美元。 } 为了处理唯一性,我有一个修改过的解决方案,它使用GNU AWK的长度函数,同样在Mac OS X上的nawk中: script.gawk NR>1{ 最后,最后 分摊0美元,现钞 删除找到的计数有多少个唯一的事件 因为我现在看到的是文字。 最后一天的j 如果last_ar[j]==curr_ar[i] 找到[curr_ar[i]]++ 如果发现长度>=3,则打印 } { 最后=0美元 } 测试: ▶ gawk-f script.gawk文件 单词9单词6单词8单词3 单向:
$ awk '{x=0;for(i=1;i<=NF;i++)if ($i in a)x++;split("",a);for(i=1;i<=NF;i++){a[$i]};}x==3' file
word9 word6 word8 word3
将行内容存储在关联数组中。然后检查关联数组并递增计数器x.单向:
$ awk '{x=0;for(i=1;i<=NF;i++)if ($i in a)x++;split("",a);for(i=1;i<=NF;i++){a[$i]};}x==3' file
word9 word6 word8 word3
将行内容存储在关联数组中。然后检查关联数组并增加计数器x。替代解决方案:
awk '{
c=0;
for(i=1;i<=NF;i++)
{
if(l[$i]){c+=1}
}
}
{
delete l;
for(i=1;i<=NF;i++)
{
l[$i]=1
}
}
c>=3' <your file>
替代解决方案:
awk '{
c=0;
for(i=1;i<=NF;i++)
{
if(l[$i]){c+=1}
}
}
{
delete l;
for(i=1;i<=NF;i++)
{
l[$i]=1
}
}
c>=3' <your file>
您可以使用哈希确保值的唯一性,下面是一个示例脚本: 解析.awk 只从第二行开始检查 NR>1{ c=0变量,用于保存公共字计数 浏览独特的单词并与前一行进行比较 因为i=1;i=N 将当前行收集到h关联数组中 {
对于i=1;i您可以通过使用哈希确保值的唯一性,下面是一个示例脚本: 解析.awk 只从第二行开始检查 NR>1{ c=0变量,用于保存公共字计数 浏览独特的单词并与前一行进行比较 因为i=1;i=N 将当前行收集到h关联数组中 {
对于i=1;i这可能适用于GNU-sed:
sed -nE 'N;h;s/(.*)(\n.*)/\n\1 \2 /;:a;s/(\n(\S+\s+).*\n.*)\2/N\1/;s/\n\S+\s+/\n/;ta;/^N{3}/{g;s/.*\n//p};g;D' file
该解决方案由三部分组成:
第一部分
一个由两行组成的移动窗口被触发
创建包含当前双线窗口的原始图案空间的副本
在模式空间前面加一个换行符,在两行的末尾加上额外的空格。换行符充当唯一字数的分隔符,空格允许每行中的最后一个字匹配
第二部分
启动模式匹配循环,其中第一个单词及其后面的空格与第二行中的任何单词匹配。如果匹配,则从第二行中删除该单词,并在引入的换行符之前递增计数器。删除第一行中的第一个单词,并重复该过程,直到出现为止第一行没有其他单词
检查计数器所需的匹配数,如果发现为真,则刷新图案空间的副本,删除第一行并打印第二行
第三部分
不管上述情况如何,都会刷新模式空间,删除第一行并重复该过程,直到文件结束
上述解决方案打印N行或多行匹配项。在上述解决方案中,N设置为3,如OP示例中的N only matches use:
sed -nE 'N;h;s/(.*)(\n.*)/\n\1 \2 /;:a;s/(\n(\S+\s+).*\n.*)\2/N\1/;s/\n\S+\s+/\n/;ta;/^N{3}\n/{g;s/.*\n//p};g;D' file
这可能适用于GNU sed:
sed -nE 'N;h;s/(.*)(\n.*)/\n\1 \2 /;:a;s/(\n(\S+\s+).*\n.*)\2/N\1/;s/\n\S+\s+/\n/;ta;/^N{3}/{g;s/.*\n//p};g;D' file
该解决方案由三部分组成:
第一部分
一个由两行组成的移动窗口被触发
创建包含当前双线窗口的原始图案空间的副本
在模式空间前面加一个换行符,在两行的末尾加上额外的空格。换行符充当唯一字数的分隔符,空格允许每行中的最后一个字匹配
第二部分
启动模式匹配循环,其中第一个单词及其后面的空格与第二行中的任何单词匹配。如果匹配,则从第二行中删除该单词,并在引入的换行符之前递增计数器。删除第一行中的第一个单词,并重复该过程,直到
l第一行中没有其他单词
检查计数器所需的匹配数,如果发现为真,则刷新图案空间的副本,删除第一行并打印第二行
第三部分
不管上述情况如何,都会刷新模式空间,删除第一行并重复该过程,直到文件结束
上述解决方案打印N行或多行匹配项。在上述解决方案中,N设置为3,如OP示例中的N only matches use:
sed -nE 'N;h;s/(.*)(\n.*)/\n\1 \2 /;:a;s/(\n(\S+\s+).*\n.*)\2/N\1/;s/\n\S+\s+/\n/;ta;/^N{3}\n/{g;s/.*\n//p};g;D' file
如果您的数据在d文件中,请在gnu awk上尝试
awk 'NR==1{for(;i++<NF;)a[i]=$i;next} {for(i=0;i++<NF;){for(j in a){if($i==a[j])c++;if(c==3){print;exit}}}; c=0;i=length(a);NF+=i;for(j=0;i<NF;)a[++i]=$++j} ' d
如果您的数据在d文件中,请在gnu awk上尝试
awk 'NR==1{for(;i++<NF;)a[i]=$i;next} {for(i=0;i++<NF;){for(j in a){if($i==a[j])c++;if(c==3){print;exit}}}; c=0;i=length(a);NF+=i;for(j=0;i<NF;)a[++i]=$++j} ' d
到目前为止你尝试了什么?我已经解决了,但公平地说,@Thor's应该是公认的答案。@AlexHarvey:不担心你到目前为止尝试了什么?我已经解决了,但公平地说,@Thor's应该是公认的答案。@AlexHarvey:不用担心,永远不要使用名为l的变量,因为它看起来太多了,所以会混淆你的代码。永远不要使用名为l的变量,因为它看起来太多了,所以会混淆你的代码。