根据条件 Linux 从多行文本文件的每一行中提取文本

Extract text from each line from a multiple-line text file based on a condition, Linux

我有一个只有一列的 txt 文件,每一行代表来自序列输出的不同 fastq.gz 文件。请参阅下面的示例:

36108-ABZG339L_S237_L001_R1_001.fastq.gz
36108-ABZG339L_S237_L001_R2_001.fastq.gz
36108-ABZGM_S7_L001_R1_001.fastq.gz
36108-ABZGM_S7_L001_R2_001.fastq.gz

首先,我想将第一个“-”符号转换为下划线“_”。

我通过以下命令实现了:

sed 's/[-]/_/Ig' inputfile.txt > outputfile.txt

那么outputfile.txt就是:

36108_ABZG339L_S237_L001_R1_001.fastq.gz
36108_ABZG339L_S237_L001_R2_001.fastq.gz
36108_ABZGM_S7_L001_R1_001.fastq.gz
36108_ABZGM_S7_L001_R2_001.fastq.gz

之后,我想在一个新的 txt 文件中只提取第一个和第二个下划线之间的文本,所以:

ABZG339L
ABZG339L
ABZGM
ABZGM

我怎样才能实现?我试过 sed、awk 但我找不到。

预先感谢您的帮助,

魔法师

第一个解决方案: 要获得显示的预期示例输出,您无需先将 - 替换为 - 然后打印,我们可以在这里使用 awk 的力量来创建多个字段分隔符,然后相应地打印所需的值。

awk -F'-|_' '{print }' Input_file

解释: 上面 awk 程序的简单解释是,使 _- 作为整个 Input_file 的字段分隔符,然后在其中打印第二个 field/column。



第二种方案:使用sed方案,这里使用sed的反向引用能力。

sed -E 's/^[^-]*-([^_]*).*//' Input_file

说明:这里使用sed-E选项启用ERE(扩展正则表达式)这里。在 sed 的主程序中,然后从值的开始到第一次出现 - 匹配它,然后创建第一个反向引用(内存中的临时位置,稍后在执行替换时检索)然后匹配任何东西直到最后的价值。替换时,将整行值替换为仅匹配的值以获得所需的结果。



第三个解决方案: 这里使用 GNU grep。在此处使用 GNU grep-oP 选项在该程序中启用 PCRE 正则表达式引擎。在主程序中匹配从开始到直到的所有内容 - 并忘记与 GNU grep\k 选项匹配。然后匹配 - 之前的所有内容并打印出来。

grep -oP '^.*?-\K[^_]*' Input_file