从 Linux 中的文件中提取文本:特定行;在两种不同的模式之间
Extract text from file in Linux: specific line; between 2 different patterns
我有一堆文本文件,都具有相同的结构,我需要提取特定行中的特定片段。
我可以很容易地用 awk 提取行:
awk 'NR==23' blast_out.txt
CP046310.1 Lactobacillus jensenii strain FDAARGOS_749 chromosome,... 787 0.0
但我不想要整行,而只想要左边的第一个 space(CP046310.1
之后)和右边的双 space 之间的部分( 787
之前)。最终输出应该是:
Lactobacillus jensenii strain FDAARGOS_749 chromosome,...
我尝试了几种 awk 和 grep 的组合,但找不到正确的组合来提取此特定模式。
第一个解决方案: 使用您显示的示例,请尝试遵循 awk
代码。简单的解释是,取消第一个、第二个最后一个字段和最后一个字段,然后全局用 NULL 替换开始和结束 space,然后打印该行。
awk '{=$NF=$(NF-1)="";gsub(/^ +| +$/,"")} 1' Input_file
OR 到 运行 它在第 23 行将其更改为:
awk 'FNR==23{=$NF=$(NF-1)="";gsub(/^ +| +$/,"");print;exit}' Input_file
第二个解决方案:根据需要遍历字段并打印所需的值。
awk '{for(i=2;i<(NF-1);i++){printf("%s%s",$i,i==(NF-2)?ORS:OFS)}}' Input_file
OR 在第 23 行尝试以下操作:
awk 'FNR==23{for(i=2;i<(NF-1);i++){printf("%s%s",$i,i==(NF-2)?ORS:OFS)};exit}' Input_file
使用 sed
你可以使用这个解决方案:
sed -En '23s/^[^ ]+ | .*$//gp' file
Lactobacillus jensenii strain FDAARGOS_749 chromosome,...
或使用awk
:
awk 'NR == 23 {gsub(/^[^ ]+ | .*$/, ""); print}' file
如果我明白你的要求,你想提取从第二个(包括)到 second-last(排除)的字段。
我会选择:
awk ' FNR==23 {for (i = 2; i < NF - 2; i++) { printf("%s ", $i) }; printf("%s\n", $i); exit }' file_path
您发布的行的示例:
$ echo "CP046310.1 Lactobacillus jensenii strain FDAARGOS_749 chromosome,... 787 0.0" | awk '{for (i = 2; i < NF - 2; i++) { printf("%s ", $i) }; printf("%s\n", $i); exit }'
$ Lactobacillus jensenii strain FDAARGOS_749 chromosome,...
我假设 chromosome,...
不包含空格,并且您只有一个空格分隔要提取的字段。如果第二个条件不成立,那些多余的空格将被删除。
使用 Perl:
echo "CP046310.1 Lactobacillus jensenii strain FDAARGOS_749 chromosome,... 787 0.0"|perl -ne 'm/ (.*?) /; print '
我有一堆文本文件,都具有相同的结构,我需要提取特定行中的特定片段。
我可以很容易地用 awk 提取行:
awk 'NR==23' blast_out.txt
CP046310.1 Lactobacillus jensenii strain FDAARGOS_749 chromosome,... 787 0.0
但我不想要整行,而只想要左边的第一个 space(CP046310.1
之后)和右边的双 space 之间的部分( 787
之前)。最终输出应该是:
Lactobacillus jensenii strain FDAARGOS_749 chromosome,...
我尝试了几种 awk 和 grep 的组合,但找不到正确的组合来提取此特定模式。
第一个解决方案: 使用您显示的示例,请尝试遵循 awk
代码。简单的解释是,取消第一个、第二个最后一个字段和最后一个字段,然后全局用 NULL 替换开始和结束 space,然后打印该行。
awk '{=$NF=$(NF-1)="";gsub(/^ +| +$/,"")} 1' Input_file
OR 到 运行 它在第 23 行将其更改为:
awk 'FNR==23{=$NF=$(NF-1)="";gsub(/^ +| +$/,"");print;exit}' Input_file
第二个解决方案:根据需要遍历字段并打印所需的值。
awk '{for(i=2;i<(NF-1);i++){printf("%s%s",$i,i==(NF-2)?ORS:OFS)}}' Input_file
OR 在第 23 行尝试以下操作:
awk 'FNR==23{for(i=2;i<(NF-1);i++){printf("%s%s",$i,i==(NF-2)?ORS:OFS)};exit}' Input_file
使用 sed
你可以使用这个解决方案:
sed -En '23s/^[^ ]+ | .*$//gp' file
Lactobacillus jensenii strain FDAARGOS_749 chromosome,...
或使用awk
:
awk 'NR == 23 {gsub(/^[^ ]+ | .*$/, ""); print}' file
如果我明白你的要求,你想提取从第二个(包括)到 second-last(排除)的字段。 我会选择:
awk ' FNR==23 {for (i = 2; i < NF - 2; i++) { printf("%s ", $i) }; printf("%s\n", $i); exit }' file_path
您发布的行的示例:
$ echo "CP046310.1 Lactobacillus jensenii strain FDAARGOS_749 chromosome,... 787 0.0" | awk '{for (i = 2; i < NF - 2; i++) { printf("%s ", $i) }; printf("%s\n", $i); exit }'
$ Lactobacillus jensenii strain FDAARGOS_749 chromosome,...
我假设 chromosome,...
不包含空格,并且您只有一个空格分隔要提取的字段。如果第二个条件不成立,那些多余的空格将被删除。
使用 Perl:
echo "CP046310.1 Lactobacillus jensenii strain FDAARGOS_749 chromosome,... 787 0.0"|perl -ne 'm/ (.*?) /; print '