我有一个包含文本和数字组合的制表符分隔文件。我想保留每一行原样,但我想只保留第五列中的六位数字(如果存在)。例如:
gene1 NM_033629 598G>A P912 syndrome 1, 192315 syndrome 2, 225750 syndrome 3 610448 score AD hom user 123456 Source
gene2 NM_000459 613G>A V115I syndrome 1 600195 score AD rec user 234567 Source
(Syndrome # 用作示例,这可以是任何文本,因此不是我可以搜索和删除的模式)
我希望输出是:
gene1 NM_033629 598G>A P912 192315 225750 610448 score AD hom user 123456 Source
gene2 NM_000459 613G>A V115I 600195 score AD rec user 234567 Source
我有 4 种方法来提取 6 位数字,但是我不能
A。输出它源自的行中的数字
b.成功打印包含一个已编辑字段的整行。我用来提取数字的选项是:
cat inputfile | cut -f 5 |grep -P '(? < !\d)\d{6}(?!\d)'
cat inputfile | cut -f 5 |grep -Po '(?< !\d)\d{6}(?!\d)'
cat inputfile | cut -f 5 |grep -o '[[:digit:]]*'
cat inputfile | cut -f 5 |grep -o "[0-9]\{6\}"
我知道对列使用 cut 是不正确的,但我想确保提取正确,因为字段 9 中还有一个六位数字。我坚持将所有这些放在一起。在此先感谢您的任何建议
答案1
如果我理解正确的话,你希望第五列成为其中所有 6 位数字与空格的串联。
或许:
perl -F'\t' -lape '
$F[4] = join " ", grep {length == 6} ($F[4] =~ /\d+/g);
$_ = join "\t", @F' < file
或者重复使用你对操作员的负面看法:
perl -F'\t' -lape '
$F[4] = join " ", ($F[4] =~ /(?<!\d)\d{6}(?!\d)/g);
$_ = join "\t", @F' < file
和awk
:
awk -F'\t' -v OFS='\t' '
{
repl = sep = ""
while (match($5, /[0-9]+/)) {
if (RLENGTH == 6) {
repl = repl sep substr($5, RSTART, RLENGTH)
sep = " "
}
$5 = substr($5, RSTART+RLENGTH)
}
$5 = repl
print
}' < file
grep
其本身并不足以完成这项任务。grep
旨在打印与模式匹配的行。一些实现如 GNU 或 ast-open grep
,或者pcregrep
可以从匹配行中提取字符串,但这非常有限。
我能想到的唯一可以在某些限制下工作的 ++cut
方法是实现:grep
paste
pcregrep
grep
n='(?:.*?((?1)))?'
paste <(< file cut -f1-4) <(< file cut -f5 |
pcregrep --om-separator=" " -o1 -o2 -o3 -o4 -o5 -o6 -o7 -o8 -o9 \
"((?<!\d)\d{6}(?!\d))$n$n$n$n$n$n$n$n"
) <(< file cut -f6-)
假设每行输入至少有 6 个字段,并且每个字段的第 5 个字段有 1 到 9 个 6 位数字。
答案2
awk '
BEGIN {
FS = "\t";
OFS = "\t";
}
{
cnt = patsplit($5, arr, /[0-9]{6}/);
$5 = arr[1];
for(i = 2; i <= cnt; i++) {
$5 = $5 " " arr[i];
}
print;
}' input.txt
patsplit(s, a [, r [, seps] ])- 分割字符串 s进入数组A和分隔符数组塞普斯在正则表达式上r,并返回字段数。 元素值是 s 中与 r 匹配的部分。
输入:
gene1 NM_033629 598G>A P912 syndrome 1, 192315 syndrome 2, 225750 syndrome 3 610448 score AD hom user 123456 Source
gene2 NM_000459 613G>A V115I syndrome 1 600195 score AD rec user 234567 Source
输出:
gene1 NM_033629 598G>A P912 192315 225750 610448 score AD hom user 123456 Source
gene2 NM_000459 613G>A V115I 600195 score AD rec user 234567 Source