从文件中打印与第二列中的模式列表匹配的单行
print single line from file that matches list of patterns in the second column
编辑:我在 Linux 集群中工作。
我有一个很大的文件,在第一列中列出了一个 ID,第二列是原始文件中第 4-5-6 列中复制的列的组合。输入文件如下所示:
1 1:71:T:C 0 71 C T
1 1:71:T:A 0 71 A T
1 1:72:GTGTGTGTT:G 0 72 G GTGTGTGTT
1 1:75:T:C 0 75 C T
1 1:75:T:* 0 75 * T
1 1:76:GTGTT:G 0 76 G GTGTT
1 1:76:GTGTT:* 0 76 * GTGTT
1 1:83:C:CAT 0 83 CAT C
1 1:87:CGT:C 0 87 C CGT
1 1:87:C:CGTGTGT 0 87 CGTGTGT C
U U:19874536:G:A 0 19874536 A G
U U:19874560:G:A 0 19874560 A G
U U:19874575:C:T 0 19874575 T C
U U:19874577:T:G 0 19874577 G T
U U:19874587:CA:C 0 19874587 C CA
U U:19874587:CAA:C 0 19874587 C CAA
U U:19874602:C:T 0 19874602 T C
U U:19876478:T:C 0 19876478 C T
U U:19876534:C:A 0 19876534 A C
U U:19876568:T:C 0 19876568 C T
22 X:29:G:GT 0 29 G GT
22 X:96:T:A 0 96 A T
22 X:146:A:G 0 146 G A
22 X:167:A:T 0 167 T A
22 X:168:T:C 0 168 C T
22 X:244:C:T 0 244 T C
22 X:253:C:A 0 253 A C
22 X:254:C:A 0 254 A C
22 X:330:G:T 0 330 T G
22 X:371:GGCGTTTACGT:G 0 371 G GGCGTTTACGT
.
.
.
我正在尝试检查第 1 列 (ID) 如何与第 2 列中的原始 ID 匹配,所以我只想打印与原始 ID 列表匹配的第一行(在第二列中).我希望这很清楚!我看到 ,我认为它应该可以帮助我,但我不熟悉 awk 并且我不知道如何编辑它所以匹配仅指 ID(在 ' :') 在第 2 列中。
编辑:预期输出:
1 1:71:T:C 0 71 C T
U U:19874536:G:A 0 19874536 A G
22 X:29:G:GT 0 29 G GT
.
.
.
Perl 解决方案:
perl -F'/[\s:]+/' -lane 'BEGIN { %matches = ( 22 => "X", ); } print if ( ( $F[0] eq $F[1] || $F[1] eq $matches{ $F[0] } ) && !$seen{ $F[0] }++ ); ' infile > outfile
Perl one-liner 使用这些命令行标志:
-e
:告诉 Perl 查找代码 in-line,而不是在文件中。
-n
:一次循环输入一行,默认分配给 $_
。
-l
: 在执行代码 in-line 之前去除输入行分隔符(默认情况下在 *NIX 上为 "\n"
),并在打印时附加它。
-a
: 在空格或 -F
选项中指定的正则表达式上将 $_
拆分为数组 @F
。
-F'/[\s:]+/'
:在空白处或 :
处拆分为 @F
,重复 1 次或多次,而不是在空白处。
%matches = ( 22 => "X", );
- 创建哈希 [=24=],它将匹配的 ID 从第 1 列映射到第 2 列。为了速度,它被放置在 BEGIN { ... }
块中,它只执行一次在脚本的开头,在后续代码之前是 运行,即每个输入行都是 运行。
!$seen{ $F[0] }++
:仅当每个值在第一列中第一次出现时才为真。
另请参见:
perldoc perlrun
: how to execute the Perl interpreter: command line switches
编辑:我在 Linux 集群中工作。
我有一个很大的文件,在第一列中列出了一个 ID,第二列是原始文件中第 4-5-6 列中复制的列的组合。输入文件如下所示:
1 1:71:T:C 0 71 C T
1 1:71:T:A 0 71 A T
1 1:72:GTGTGTGTT:G 0 72 G GTGTGTGTT
1 1:75:T:C 0 75 C T
1 1:75:T:* 0 75 * T
1 1:76:GTGTT:G 0 76 G GTGTT
1 1:76:GTGTT:* 0 76 * GTGTT
1 1:83:C:CAT 0 83 CAT C
1 1:87:CGT:C 0 87 C CGT
1 1:87:C:CGTGTGT 0 87 CGTGTGT C
U U:19874536:G:A 0 19874536 A G
U U:19874560:G:A 0 19874560 A G
U U:19874575:C:T 0 19874575 T C
U U:19874577:T:G 0 19874577 G T
U U:19874587:CA:C 0 19874587 C CA
U U:19874587:CAA:C 0 19874587 C CAA
U U:19874602:C:T 0 19874602 T C
U U:19876478:T:C 0 19876478 C T
U U:19876534:C:A 0 19876534 A C
U U:19876568:T:C 0 19876568 C T
22 X:29:G:GT 0 29 G GT
22 X:96:T:A 0 96 A T
22 X:146:A:G 0 146 G A
22 X:167:A:T 0 167 T A
22 X:168:T:C 0 168 C T
22 X:244:C:T 0 244 T C
22 X:253:C:A 0 253 A C
22 X:254:C:A 0 254 A C
22 X:330:G:T 0 330 T G
22 X:371:GGCGTTTACGT:G 0 371 G GGCGTTTACGT
.
.
.
我正在尝试检查第 1 列 (ID) 如何与第 2 列中的原始 ID 匹配,所以我只想打印与原始 ID 列表匹配的第一行(在第二列中).我希望这很清楚!我看到
编辑:预期输出:
1 1:71:T:C 0 71 C T
U U:19874536:G:A 0 19874536 A G
22 X:29:G:GT 0 29 G GT
.
.
.
Perl 解决方案:
perl -F'/[\s:]+/' -lane 'BEGIN { %matches = ( 22 => "X", ); } print if ( ( $F[0] eq $F[1] || $F[1] eq $matches{ $F[0] } ) && !$seen{ $F[0] }++ ); ' infile > outfile
Perl one-liner 使用这些命令行标志:
-e
:告诉 Perl 查找代码 in-line,而不是在文件中。
-n
:一次循环输入一行,默认分配给 $_
。
-l
: 在执行代码 in-line 之前去除输入行分隔符(默认情况下在 *NIX 上为 "\n"
),并在打印时附加它。
-a
: 在空格或 -F
选项中指定的正则表达式上将 $_
拆分为数组 @F
。
-F'/[\s:]+/'
:在空白处或 :
处拆分为 @F
,重复 1 次或多次,而不是在空白处。
%matches = ( 22 => "X", );
- 创建哈希 [=24=],它将匹配的 ID 从第 1 列映射到第 2 列。为了速度,它被放置在 BEGIN { ... }
块中,它只执行一次在脚本的开头,在后续代码之前是 运行,即每个输入行都是 运行。
!$seen{ $F[0] }++
:仅当每个值在第一列中第一次出现时才为真。
另请参见:
perldoc perlrun
: how to execute the Perl interpreter: command line switches