Shell 各种文件中各种元素的计数

Shell 各种文件中各种元素的计数,shell,unix,sed,awk,grep,Shell,Unix,Sed,Awk,Grep,所以我有大约1000个文件是多列的,但我只对其中两列的一些统计数据感兴趣。如果4美元是一颗恒星的光谱等级(即唯一值),而每个文件中的5美元是一个结果,比如看到的、看不见的、未知的,等等,那么有没有推荐的方法可以在1000个左右的文件中对这样的统计数据进行grep或awk,这样我就可以得到如下结果: Type O, #verified, #not-verified, #property-j, ... Type B, ... Type A, ... . . . Type i, $1, $2, $3

所以我有大约1000个文件是多列的,但我只对其中两列的一些统计数据感兴趣。如果4美元是一颗恒星的光谱等级(即唯一值),而每个文件中的5美元是一个结果,比如看到的、看不见的、未知的,等等,那么有没有推荐的方法可以在1000个左右的文件中对这样的统计数据进行grep或awk,这样我就可以得到如下结果:

Type O, #verified, #not-verified, #property-j, ...
Type B, ...
Type A, ...
.
.
.
Type i,
$1, $2, $3, Spectral Type, Result
foo, foo, foo, A, verified
foo, foo, foo, G, verified
foo, foo, foo, A, unknown
foo, foo, foo, F, verified
foo, foo, foo, G, verified
foo, foo, foo, K, verified
foo, foo, foo, K, seen
其中,在每个文件中,您会看到如下内容:

Type O, #verified, #not-verified, #property-j, ...
Type B, ...
Type A, ...
.
.
.
Type i,
$1, $2, $3, Spectral Type, Result
foo, foo, foo, A, verified
foo, foo, foo, G, verified
foo, foo, foo, A, unknown
foo, foo, foo, F, verified
foo, foo, foo, G, verified
foo, foo, foo, K, verified
foo, foo, foo, K, seen

如果分隔符只是逗号,不需要CSV解析和转义,请使用剪切实用程序:

cat $file | cut -d, -f4

如果分隔符只是逗号,不需要CSV解析和转义,请使用剪切实用程序:

cat $file | cut -d, -f4
如果您的问题是:“如何生成表单“Type$4、$5”的输出,其中$4和$5分别是输入的第4列和第5列?”一个解决方案是:

for i in list of input file; do
  awk '{print "Type "$4, $5}' $i > $i.result
done
这将提供您想要的输出,但依赖于不包含空格的所有列。如果可能存在空白,您可以执行以下操作:

 awk '{printf( "Type %s, %s", $4, $5 )}' FS=, $i > $i.result
但是,您可能需要修剪这将生成的额外空白。请注意,尽管在示例中,我已将输入文件列表硬编码为4个文件名“list”、“of”、“input”和“file”,但我不希望您键入这些名称。相反,您应该以某种方式生成它们,我只是演示了在一组文件上迭代的一种(多种)方法。这个问题的核心似乎是处理
awk
的部分,而不是迭代

对问题的二读表明,每个输入文件正好有一行,并且希望在单个文件中汇总结果。在这种情况下,只需执行以下操作:

cat list of all files | awk '{print "Type "$4, $5}'
如果您的问题是:“如何生成表单“Type$4、$5”的输出,其中$4和$5分别是输入的第4列和第5列?”一个解决方案是:

for i in list of input file; do
  awk '{print "Type "$4, $5}' $i > $i.result
done
这将提供您想要的输出,但依赖于不包含空格的所有列。如果可能存在空白,您可以执行以下操作:

 awk '{printf( "Type %s, %s", $4, $5 )}' FS=, $i > $i.result
但是,您可能需要修剪这将生成的额外空白。请注意,尽管在示例中,我已将输入文件列表硬编码为4个文件名“list”、“of”、“input”和“file”,但我不希望您键入这些名称。相反,您应该以某种方式生成它们,我只是演示了在一组文件上迭代的一种(多种)方法。这个问题的核心似乎是处理
awk
的部分,而不是迭代

对问题的二读表明,每个输入文件正好有一行,并且希望在单个文件中汇总结果。在这种情况下,只需执行以下操作:

cat list of all files | awk '{print "Type "$4, $5}'
编辑

为什么这解决了问题

对于标志信息类型

perl --help
算法

{..} END{..}    # first block is evaluated on each line, END block only once at the end
@F[3]应该写为$F[3],区别在于@F[3]是一个元素数组,$F[3]是元素

${h{$F[3]}}     # gets value or creates and return a new entry in the hash %h with key $F[3] third element of array @F
${..}{$F[4]}=1  # supposes that value in hash %h is type HASHREF and creates a new entry with key 
整个表达式都可以编写(可能更容易),但我首先想到的是第一种语法

$h{$F[3]}{$F[4]}=1
结束

更接近问题的解决方案:

perl -lnaF'/\s*,\s*/' -e '{$h{$F[3]}{$F[4]}=1;}END{while(($k,$v)=each%h){print("Type $k, ",join(", ",map("#$_",keys%$v)));}}'
注意:在这种情况下,打印后的括号是可选的,但为了更易于阅读,在关闭curly braket之前保留分号

编辑

为什么这解决了问题

对于标志信息类型

perl --help
算法

{..} END{..}    # first block is evaluated on each line, END block only once at the end
@F[3]应该写为$F[3],区别在于@F[3]是一个元素数组,$F[3]是元素

${h{$F[3]}}     # gets value or creates and return a new entry in the hash %h with key $F[3] third element of array @F
${..}{$F[4]}=1  # supposes that value in hash %h is type HASHREF and creates a new entry with key 
整个表达式都可以编写(可能更容易),但我首先想到的是第一种语法

$h{$F[3]}{$F[4]}=1
结束

更接近问题的解决方案:

perl -lnaF'/\s*,\s*/' -e '{$h{$F[3]}{$F[4]}=1;}END{while(($k,$v)=each%h){print("Type $k, ",join(", ",map("#$_",keys%$v)));}}'

注意:在这种情况下,打印后的括号是可选的,但为了更易于阅读,在关闭curly braket之前保留分号

对不起,我的意思是,问题的第二部分是将结果文件中各种类型的统计数据制成表格,而不仅仅是读取它们是什么。使用awk提取我想要分析的列效果很好,但是如果我提取了这两列并想要查看已验证、未知、已看到等的计数,那么我应该怎么做?您应该将它们相加并输出总和!抱歉,我的意思是,问题的第二部分是将结果文件中各种类型的统计数据制成表格,而不仅仅是读取它们是什么。使用awk提取我想要分析的列效果很好,但是如果我提取了这两列并想要查看已验证、未知、已看到等的计数,那么我应该怎么做?您应该将它们相加并输出总和!我们需要一个更好的示例来说明您所需的输出,以便提出任何有意义的评论或建议。祝你好运。我们需要一个更好的例子来说明你需要的输出,以便提出任何有意义的评论或建议。祝你好运