ファイルの各行に新しい要素を追加する方法

ファイルの各行に新しい要素を追加する方法

次の内容を含むファイルがあります。

CHROM_POS
chr10_100009635
chr10_100187980
chr10_100229692
chr10_100267650
chr10_100269675
chr10_100279430
chr10_100285899

このファイルに新しいコンテンツを追加したいと思います。たとえば、次のようになります。

chrX-1, chrX

ここで、Xは上記の数字を表しているため、次のようになります。

chr10_100285898 chr10_100285899

答え1

Perlソリューション:

perl -p -e 's;([^_]+)_(\d+);"$1_" . ($2 - 1) . " $1_$2";e'

この-pフラグは、すべての行を繰り返して-eスクリプトを引数として提供します。([^_]+)アクティベーション式を置き換えるために、e `修飾子の前にあるものを(\ d +)$ 2キャプチャします。_$1captures the digits into, the

入力ファイルを引数として使用するか、標準入力として使用してください。

答え2

使用awk:

awk -F _ 'NR > 1 { $0 = sprintf("%s_%d, %s_%d", $1, $2-1, $1, $2) }; 1' file

または少し短く、

awk -F _ 'NR > 1 { $0 = sprintf("%s_%d, %s", $1, $2-1, $0) }; 1' file

これは、最初の行をそのまま残し、結果列の間にカンマを入れたいとします。sprintf()カンマが必要ない場合は、フォーマット文字列からコンマを削除します。

このコードは最初の行では何もしませんが、パターンにsprintf()基づいて他のすべての行を書き直します。chrX_(N-1), chrX_Nこれはまさにユーザーが要求するようです。

データを2つの別々の_フィールド、すなわち染色体名と染色体のゲノム位置として処理して、元の行のビットを選択しました。だから染色体名は で読み込まれ$1、位置は で読み込まれます$2

コードの1最後の部分awkでは、データ(変更の有無にかかわらず)が出力されます。

与えられたサンプルデータを出力します。

CHROM_POS
chr10_100009634, chr10_100009635
chr10_100187979, chr10_100187980
chr10_100229691, chr10_100229692
chr10_100267649, chr10_100267650
chr10_100269674, chr10_100269675
chr10_100279429, chr10_100279430
chr10_100285898, chr10_100285899

答え3

Awkベースのソリューション:

awk -F '_' -v OFS=, 'NR>1{ $0 = $1 FS $2-1 OFS $0 }1' file

結果:-

CHROM_POS
chr10_100009634,chr10_100009635
chr10_100187979,chr10_100187980
chr10_100229691,chr10_100229692
chr10_100267649,chr10_100267650
chr10_100269674,chr10_100269675
chr10_100279429,chr10_100279430
chr10_100285898,chr10_100285899

他の方法:

[パール]

perl -lsne '
  print $.>1 ? s/(\d+)$/$1-1/re : (), $_;
' -- -,=, file

[Python3]

python3 -c 'import sys
with open(sys.argv[1]) as f:
  for nr,_ in enumerate(f,1):
    _ = _.rstrip("\n")
    if nr > 1:
      p = _.find("_") + 1
      _ = _[:p] + f"{int(_[p:])-1}," + _
    print(_)
' file

[GNU dc] RPN電卓

< file \
sed 's/^/[/;1s/$/]/;1!s/_/&]/' |
dc ​-e "
[q]sq
[rdnrd1-n44anrnpc]sp
[?z0=q lpx z0=?]s?
?pc l?x
"

[GNU sed]

sed -Ee '1b
  h
  s/^[^_]*_//
  s/$/\n9876543210/;tdecr
  :decr
  s/([^0])\n.*\1(.).*/\2/;tdone
  s/([^0])(0+\n.*\1(.))/\3_\2/
  :loop
    s/_0(0*\n)/9_\1/
  tloop
  s/_.*//
  :done
  G
  s/.*\n([^_]*_)/\1&/
  y/\n/,/
' file

関連情報