![计算字符串中的相对位置](https://linux22.com/image/40742/%E8%AE%A1%E7%AE%97%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E7%9B%B8%E5%AF%B9%E4%BD%8D%E7%BD%AE.png)
输入文件示例:
#name complete(cs) len(cs) simple(ss) len(ss) position(ss)
NAME1 A0AAA000AAA00A 14 AAAAAAAA 8 4,6
NAME2 AAAA0AA00000A 13 AAAAAAA 7 7
假设我有兴趣了解在位置(ss)列中给出的简化字符串(ss)的一些字母在完整字符串(cs)中的相应位置。 注意:在简单字符串(ss)中,只允许使用字母。在完整的字符串中,每个字符都是允许的。
在此示例中,它将返回:
示例输出文件:
#name complete(cs) len(cs) simple(ss) len(ss) pos(ss) pos(cs)
NAME1 A0AAA000AAA00A 14 AAAAAAAA 8 4,6 5,10
NAME2 AAAA0AA00000A 13 AAAAAAA 7 7 13
我目前正在使用 python 构建这个文件,但我确信有一个简单的 Unix 出路。
答案1
一个perl
办法:
$ perl -anle '
print "$_ position(cs)" and next if /^#/;
printf "%s",$_;
for $pos_ss (split ",",$F[5]) {
$char = substr($F[3],$pos_ss-1,1);
@cs = split //,$F[1];
@cs_idx = grep {$cs[$_] eq $char} 0..$#cs;
push @res,++$cs_idx[$pos_ss-1];
}
printf "%14s\n", join ",",@res;
@res=();
' file
#name complete(cs) len(cs) simple(ss) len(ss) position(ss) position(cs)
NAME1 A0AAA000AAA00A 14 AAAAAAAA 8 4,6 5,10
NAME2 AAAA0AA00000A 13 AAAAAAA 7 7 13
它是如何工作的
- 前两行打印原始条目。
for $pos_ss (split ",",$F[5])
:我们拆分字段 6,在简单字符串中获取所需的每个索引。$char = substr($F[3],$pos_ss-1,1)
:获取简单字符串中给定索引处的字符。@cs = split //,$F[1]
:我们获取完整字符串中的所有字符,将它们保存到数组中。@cs_idx = grep {$cs[$_] eq $char} 0..$#cs
:获取数组中所有@cs
值相等的索引$char
。push @res,++$cs_idx[$pos_ss-1]
:保存我们想要数组的索引@res
。- 最后两行只是打印我们得到的结果和空
@res
数组以供下次使用。
答案2
这可以从 bash 运算符和硬编码信息开始。这是非常不言而喻的:
#!/bin/bash
word="A0AAA000AAA00A"
required=(4 6)
match="A"
w=$word
# get the positions of $match in $word
while [ ! -z "$w" ]; do
n=$(expr index "$w" $match)
w=${w:$n}
counter=$(( counter + n ))
# echo "position $counter. now w=$w"
pos+=($counter)
done
echo "All positions: ${pos[@]}"
# print the position of $match in $word on positions given by $required
for i in "${required[@]}"
do
echo "position $i: ${pos[i-1]}"
done
可以使用某种 来完成一般情况while read; do... done < file
,获取必要的列。