我有一个逗号分隔的文件,它不是标准的 csv 文件,如下所示:
XYZ,143,ABC/genomes/date/pa341,dog,available
567,FTR/genomes/date/ha76870,horse,waiting
214,GEN/genomes/date/btr256,N/A,avialable,stored
...
我想提取所有以“/genomes”开头的字符串,直到下一个逗号“,”字符。预期输出为:
/genomes/date/pa341
/genomes/date/ha76870
/genomes/date/btr256
我已尝试以下操作,但它打印了我不需要的额外信息:
grep -o '/genomes.*,' myfile.txt
output:
/genomes/date/pa341,dog,
/genomes/date/ha76870,horse,
/genomes/date/btr256,N/A,stored
答案1
您的方法失败了,因为*
意味着“匹配最长的可能字符串”。这称为“贪婪”修饰符。您想要“匹配最短的可能字符串”,这是一个非贪婪运算符。因此,如果您grep
支持它,请使用-P
启用扩展正则表达式并运行:
$ grep -Po '/genomes.*?,' file
/genomes/date/pa341,
/genomes/date/ha76870,
/genomes/date/btr256,
然而,更好的方法是匹配,
尽可能多的非字符:
$ grep -o '/genomes[^,]*' file
/genomes/date/pa341
/genomes/date/ha76870
/genomes/date/btr256
答案2
以下是获取信息的几种方法:
$ grep -oP '/genomes((?!,).)*' myfile.txt
$ perl -F, -pale '
shift @F until $F[0] =~ m{/genomes.*};
$_ = $&;
' myfile.txt
$ perl -lne '
my $p1 = index $_, "/genomes";
my $p2 = index $_, ",", $p1;
print substr $_, $p1, $p2-$p1;
' myfile.txt
$ sed -ne '
/\n/!s|/genomes|\n&|
y/,/\n/
/^\/genomes/!D;P
' myfile.txt
结果:
/genomes/date/pa341
/genomes/date/ha76870
/genomes/date/btr256