Shell 重映射多个字符串

Shell 重映射多个字符串,shell,awk,grep,Shell,Awk,Grep,我正在使用grep命令从文件中获取所需的信息。我使用两个grep语句,如下所示 XXXX='grep XXXX FILE A|sort|uniq|wc -l' grep YYYY FILE A|uniq| > FILE B 现在文件被遍历两次。但我只是想知道,如果我能在一个文件遍历中完成这两个步骤,也就是说,我想知道我是否能使用类似于egrep的东西,我可以grep两个字符串和一个字符串,我将使用它在变量中进行排序,并将另一个字符串输出到一个文件中 或使用带析取的egrep: egrep

我正在使用grep命令从文件中获取所需的信息。我使用两个grep语句,如下所示

XXXX='grep XXXX FILE A|sort|uniq|wc -l'
grep YYYY FILE A|uniq| > FILE B

现在文件被遍历两次。但我只是想知道,如果我能在一个文件遍历中完成这两个步骤,也就是说,我想知道我是否能使用类似于egrep的东西,我可以grep两个字符串和一个字符串,我将使用它在变量中进行排序,并将另一个字符串输出到一个文件中

或使用带析取的egrep:

egrep '(XXXX|YYYY)' FILE A | sort | uniq | ...
或awk:

awk '/XXXX|YYYY/' FILE A | sort | uniq | ...

您可以使用以下代码。在这里,我们只搜索一次所有文件中包含XXXX或YYYY的行,并将结果行存储到数组中。然后我们使用这个数组的元素来选择包含XXXX的行和包含YYYY的行

filtered=`grep -E '(XXXX|YYYY)' FILE A`
XXXX=`for line in ${filtered[@]}; do echo $line; done | grep XXXX | sort | uniq | wc -l`
for line in ${filtered[@]}; do echo $line; done | grep YYYY | uniq > FILE B

因此文件不会被遍历两次

您的问题中有一个尾随的“|”符号,您可能希望YYYY行也通过管道连接到
排序
(或使用
排序-u
!),在这种情况下,您可以简单地执行以下操作:

awk '/XXXX/ { if( !x[$0]++ ) xcount += 1 } 
     /YYYY/ { if( !y[$0]++ ) ycount += 1 }
  END { print "XXXX:", xcount
        print "YYYY:", ycount
        for( i in y ) print i | "sort > FILEB"
  }' FILE

这会扫描文件一次,每当看到包含适当模式的uniq行时,计数器就会递增。请注意,这里没有很好地定义YYYY行数组上的迭代顺序,因此需要进行排序。awk的某些版本可以在不依赖外部实用程序的情况下对阵列进行排序,但并非所有版本都可以。如果您想这样做,请使用perl。

谢谢您的回答。.我理解您的观点。。。但是我如何将两条grep语句的结果存储在两个变量中?输入数据显示得多大?这仅适用于小数据量。请看一下awk中的关联数组。输入数据的范围为200 MB。。这是一个很大的文件,现在大多数机器都有超过200MB的RAM,所以你可能会没事。如果输入数据超出可用内存,则需要采用上述管道和过滤器处理。如果输入大小大于可用内存,则此方法将迅速膨胀,并且仅适用于小数据批。如果目的是将数据存储在变量中(本问题就是这种情况)大的输入总是会填满内存。