Shell 有没有一种方法可以将列的一部分分组?

Shell 有没有一种方法可以将列的一部分分组?,shell,awk,sed,Shell,Awk,Sed,我有一个选项卡文件,如下所示: 1 56 . T C 1963 . HaplotypeScore=3.6230;MLEAF=1.00;MQ=60.00;MQ0=0;QD=33.84;MLEAC=1;SOR=1.077 1 226 . A G 1600 . HaplotypeScore=3.0421;MLEAC=1;MLEAF=1.00;MQ=59.02;MQ0=0;QD=32.00;SOR=0.954 1 670 . A G

我有一个选项卡文件,如下所示:

1   56  .   T   C   1963    .   HaplotypeScore=3.6230;MLEAF=1.00;MQ=60.00;MQ0=0;QD=33.84;MLEAC=1;SOR=1.077
1   226 .   A   G   1600    .   HaplotypeScore=3.0421;MLEAC=1;MLEAF=1.00;MQ=59.02;MQ0=0;QD=32.00;SOR=0.954
1   670 .   A   G   2878    .   HaplotypeScore=9.0166;QD=34.24;MLEAC=1;MLEAF=1.00;MQ=60.00;MQ0=0;SOR=0.864
1   817 .   C   T   1425    .   HaplotypeScore=0.9958;MLEAC=1;MLEAF=1.00;MQ=60.00;MQ0=0;QD=26.89;SOR=0.850
QD=33
QD=32
QD=34
QD=26
我的目标是创建一个for循环,从该列中单独提取
QD=
值,并生成一个.txt文件,如下所示:

1   56  .   T   C   1963    .   HaplotypeScore=3.6230;MLEAF=1.00;MQ=60.00;MQ0=0;QD=33.84;MLEAC=1;SOR=1.077
1   226 .   A   G   1600    .   HaplotypeScore=3.0421;MLEAC=1;MLEAF=1.00;MQ=59.02;MQ0=0;QD=32.00;SOR=0.954
1   670 .   A   G   2878    .   HaplotypeScore=9.0166;QD=34.24;MLEAC=1;MLEAF=1.00;MQ=60.00;MQ0=0;SOR=0.864
1   817 .   C   T   1425    .   HaplotypeScore=0.9958;MLEAC=1;MLEAF=1.00;MQ=60.00;MQ0=0;QD=26.89;SOR=0.850
QD=33
QD=32
QD=34
QD=26
到目前为止,我已经想出了这样的办法:

1   56  .   T   C   1963    .   HaplotypeScore=3.6230;MLEAF=1.00;MQ=60.00;MQ0=0;QD=33.84;MLEAC=1;SOR=1.077
1   226 .   A   G   1600    .   HaplotypeScore=3.0421;MLEAC=1;MLEAF=1.00;MQ=59.02;MQ0=0;QD=32.00;SOR=0.954
1   670 .   A   G   2878    .   HaplotypeScore=9.0166;QD=34.24;MLEAC=1;MLEAF=1.00;MQ=60.00;MQ0=0;SOR=0.864
1   817 .   C   T   1425    .   HaplotypeScore=0.9958;MLEAC=1;MLEAF=1.00;MQ=60.00;MQ0=0;QD=26.89;SOR=0.850
QD=33
QD=32
QD=34
QD=26
awk-F'[:]'{print$8}'输入文件

或者甚至可以使用sed命令。但是现在我完全迷路了。

这里:

cut -d';' -f6 file
如果这就是您所需要的,则不需要
sed
awk

要进一步仅获取整数,请执行以下操作:

cut -d';' -f6 file|cut -d. -f1
编辑 进一步的注释表明,
QD=
所在列的顺序可能会改变,因此我们可以使用正则表达式来查找它:

grep -Po 'QD=\d+' file
示例:

此处:

cut -d';' -f6 file
如果这就是您所需要的,则不需要
sed
awk

要进一步仅获取整数,请执行以下操作:

cut -d';' -f6 file|cut -d. -f1
编辑 进一步的注释表明,
QD=
所在列的顺序可能会改变,因此我们可以使用正则表达式来查找它:

grep -Po 'QD=\d+' file

示例:

您的另一个选项是
awk
,它是文本处理的瑞士军刀。它将比在大文件上生成多个子shell和将信息管道化到不同的实用程序快几个数量级。如果您的记录(行)少于1000条,则不会注意到太多差异。如果您有数百万行,那么使用
awk
只需几秒钟,或者使用多个实用程序只需几分钟

awk
处理文件中的每条记录(行),并按写入顺序将写入的规则应用于每条记录。有两个特殊规则,
BEGIN
(在开始读取行之前运行,用于分配变量、打印页眉行等)和在处理所有行之后运行的
END
规则,允许您处理数组中收集的任何数据或打印页脚行等

这里需要一条规则,根据
“;”将最后一个字段拆分为一个数组分隔符,例如

awk -F'\t' '{split($NF,arr,";"); sub(/[.].*$/,"",arr[6]); print arr[6]}' file
上面的
-F'\t'
告诉
awk
使用制表符作为字段分隔符。(注意:您可以省略
-F'\t'
,因为
awk
以空格开始分割字段),然后
split
将最后一个(
NF
)字段分割成数组
arr
,然后
sub
应用正则表达式
/.].*$/
将从
到字段结尾的所有内容切掉。
保留问题中显示的整数,例如

示例使用/输出

$ awk '{
>     split($NF,arr,";")
>     for (i in arr)
>         if (arr[i] ~ /^QD/) {
>             sub(/[.].*$/,"",arr[i])
>             print arr[i]
>             next
>         }
> }' file
QD=33
QD=32
QD=34
QD=26
使用名为
file
的文件中的示例数据,您将拥有:

$ awk -F'\t' '{split($NF,arr,";"); sub(/[.].*$/,"",arr[6]); print arr[6]}' file
QD=33
QD=32
QD=34
QD=26
(您还可以在
arr
的元素上循环查找以
“QD”
开头的元素(如果该字段发生更改)

QD位置未知

如果最后一个字段中
“QD”
的位置未知,您可以简单地循环
arr
的元素,例如
for(i in arr)
并找到以
“QD”
开头的元素,然后操作
arr[i]
,而不是
arr[6]
,例如

awk '{
    split($NF,arr,";")
    for (i in arr)
        if (arr[i] ~ /^QD/) {
            sub(/[.].*$/,"",arr[i])
            print arr[i]
            next
        }
}' file
您只需将文件名从
文件更改为任何文件名,然后选择“复制”并用鼠标中键将表达式粘贴到包含您的文件的当前工作目录中,例如

示例使用/输出

$ awk '{
>     split($NF,arr,";")
>     for (i in arr)
>         if (arr[i] ~ /^QD/) {
>             sub(/[.].*$/,"",arr[i])
>             print arr[i]
>             next
>         }
> }' file
QD=33
QD=32
QD=34
QD=26
或者,如果您喜欢将其作为一行,您可以:

$ awk '{split($NF,arr,";"); for (i in arr) if (arr[i] ~ /^QD/) { sub(/[.].*$/,"",arr[i]); print arr[i]; next }}' file
QD=33
QD=32
QD=34
QD=26

中详细介绍了使用的所有功能。这是学习
awk
的一个很好的参考。只需单击目录,然后将指向完整指南的链接添加到书签中。仔细检查一下,如果您还有其他问题,请告诉我。

您的另一个选择是
awk
,它是文本处理的瑞士军刀。它将比在大文件上生成多个子shell和将信息管道化到不同的实用程序快几个数量级。如果您的记录(行)少于1000条,则不会注意到太多差异。如果您有数百万行,那么使用
awk
只需几秒钟,或者使用多个实用程序只需几分钟

awk
处理文件中的每条记录(行),并按写入顺序将写入的规则应用于每条记录。有两个特殊规则,
BEGIN
(在开始读取行之前运行,用于分配变量、打印页眉行等)和在处理所有行之后运行的
END
规则,允许您处理数组中收集的任何数据或打印页脚行等

这里需要一条规则,根据
“;”将最后一个字段拆分为一个数组分隔符,例如

awk -F'\t' '{split($NF,arr,";"); sub(/[.].*$/,"",arr[6]); print arr[6]}' file
上面的
-F'\t'
告诉
awk
使用制表符作为字段分隔符。(注意:您可以省略
-F'\t'
,因为
awk
以空格开始分割字段),然后
split
将最后一个(
NF
)字段分割成数组
arr
,然后
sub
应用正则表达式
/.].*$/
将从
到字段结尾的所有内容切掉。
保留问题中显示的整数,例如

示例使用/输出

$ awk '{
>     split($NF,arr,";")
>     for (i in arr)
>         if (arr[i] ~ /^QD/) {
>             sub(/[.].*$/,"",arr[i])
>             print arr[i]
>             next
>         }
> }' file
QD=33
QD=32
QD=34
QD=26
使用名为
file
的文件中的示例数据,您将拥有:

$ awk -F'\t' '{split($NF,arr,";"); sub(/[.].*$/,"",arr[6]); print arr[6]}' file
QD=33
QD=32
QD=34
QD=26
(您还可以在
arr
的元素上循环查找以
“QD”
开头的元素(如果该字段发生更改)

QD位置未知

如果最后一个字段中
“QD”
的位置未知,您可以简单地循环
arr
的元素,例如
for(i in arr)
并找到以
“QD”
开头的元素,然后操作
arr[i]
,而不是
arr[6]
,例如

awk '{
    split($NF,arr,";")
    for (i in arr)
        if (arr[i] ~ /^QD/) {
            sub(/[.].*$/,"",arr[i])
            print arr[i]
            next
        }
}' file
您只需将文件名从
文件更改为任何文件名,然后选择“复制”并用鼠标中键将表达式粘贴到当前工作目录conta和xterm中即可