文字列の相対位置の計算

文字列の相対位置の計算

入力ファイルの例:

#name   complete(cs)    len(cs) simple(ss)  len(ss) position(ss)
NAME1   A0AAA000AAA00A  14      AAAAAAAA    8        4,6
NAME2   AAAA0AA00000A   13      AAAAAAA     7        7

文字列全体(cs)の位置(ss)列に指定された単純化された文字列(ss)の一部の文字に対応する場所を知りたいとします。 注:単純文字列(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

どのように動作しますか?

  • 最初の2行は元のアイテムを印刷します。
  • 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
  • 最後の2行は、我々が得た結果と、次回使用する空の@res配列を印刷します。

おすすめ記事