他のすべての列にタブを追加する

他のすべての列にタブを追加する

ファイルは次のとおりです(すべてのスペースは「単一スペース」です)。

A S1 0 0 0 -9 C C A G C C A G A A
B S2 0 0 0 -9 C C A G C C A G A A
C S3 0 0 0 -9 C C A G C C A G A A
D S4 0 0 0 -9 C C A G C C A G A A

必要なのは、2番目の列(偶数フィールド)の後のスペースをタブ(\t)に置き換えることです。予想される結果は次のとおりです。

A S1"\t"0 0"\t"0 -9"\t"C C"\t"A G"\t"C C
B S2"\t"0 0"\t"0 -9"\t"C C"\t"A G"\t"C C
C S3"\t"0 0"\t"0 -9"\t"C C"\t"A G"\t"C C
D S4"\t"0 0"\t"0 -9"\t"C C"\t"A G"\t"C C

元のファイルの列数が多かったので、コマンドラインは受動的ではありません。 (特定数のフィールドを指定します)。

この問題についてすべての人に尋ねたいです。

事前に助けてくれてありがとう。

答え1

2つのスペースを一致させ、1つを保持し、2番目のスペースを置き換えます。

sed -E 's/( [^ ]*) /\1\t/g'

答え2

力ベースのawkソリューション;) :

awk '{for (i=1;i<=NF;i++) printf("%s%s",$i,i==NF?ORS:((i%2)?" ":"\t"))}' input.txt

その後、すべてのフィールドを繰り返し、printfフィールドの内容の後に印刷するように印刷します。

  • 最後のフィールドに達すると、「出力レコード区切り記号」(デフォルトは改行)
  • そうでなく、フィールド番号が奇数の場合は空白、
  • \ta フィールド番号が偶数の場合

答え3

短くて愚かな方法ですが、16の列を扱っていることを知っていると仮定すると、完全に合法的です。

$ tr ' ' '\n' <file | paste -d ' \t' - - - - - - - - - - - - - - - -
A S1    0 0     0 -9    C C     A G     C C     A G     A A
B S2    0 0     0 -9    C C     A G     C C     A G     A A
C S3    0 0     0 -9    C C     A G     C C     A G     A A
D S4    0 0     0 -9    C C     A G     C C     A G     A A

これにより、各元のスペース区切り文字が改行文字に置き換えられます。次に、pasteスペースとタブ区切り文字が交互に表示される16列を生成する結果ストリーム(1行に1つのフィールド)を読み取ります。


awkタブ区切りペアでフィールドを印刷する場合:

$ awk -v OFS='\t' '{ nf = 0; delete a; for (i = 1; i < NF; i += 2) a[++nf]=sprintf("%s %s", $i, $(i+1)); $0 = ""; for (i = 1; i <= nf; ++i) $i = a[i]; print }' file
A S1    0 0     0 -9    C C     A G     C C     A G     A A
B S2    0 0     0 -9    C C     A G     C C     A G     A A
C S3    0 0     0 -9    C C     A G     C C     A G     A A
D S4    0 0     0 -9    C C     A G     C C     A G     A A

コードは、スペースで区切られたフィールドのペアを配列に一時的に格納しますa。これにより、その配列の要素が現在のレコードのフィールドを置き換えるために使用されます。新しいレコードは、目的の効果が得られるタブ文字を区切り文字として使用して印刷されます。

スタンドアロンawkコード:

BEGIN { OFS = "\t" }

{
    nf = 0; delete a
    for (i = 1; i < NF; i += 2)
        a[++nf] = sprintf("%s %s", $i, $(i+1))

    $0 = ""
    for (i = 1; i <= nf; ++i)
        $i = a[i]

    print
}

答え4

itertools次のモジュールを使用してください。Python 3標準ライブラリ。

python3 -c 'import sys
from itertools import zip_longest

ifile = sys.argv[1]
fs,rs,ofs = " ","\n","\t"

with open(ifile) as f:
  for l in f:
    L = l.rstrip(rs).split(fs)
    print(*[fs.join(filter(None,t))
      for t in zip_longest(L[::2],L[1::2])],sep=ofs)
' your_file.input

Pythonのzip関数は、2つ以上のイテレータ(この場合はリスト)を並列化します。 Pythonには、与えられたリストの偶数要素と奇数要素を参照するための簡潔なスライス表記[::2]と[1::2]があります。ここでは、偶数nの奇数リストからそれぞれ1つの要素を選択し、スペースで結合してペアを形成し、ペアを連結します(別名、タプルPython用語で)とタブ。

このgensub機能を使用してくださいGNU awkこれにより、入力文字列内で特定の一致番号を見つけることができます。

awk '
{
  t=$0
  for (i=2; i<NF; i++)
    t = gensub(FS, "\t", i, t)
  print t
}
' your_file.input

sedユーティリティを使用して、最初にすべてのスペースを改行文字に変換します。改行文字はパターン空間に現れないことが保証され、パターン空間に配置される前に切り捨てられる。次に、改行文字を段階的に空白に変更し、次の改行文字をタブで交互に変更します。改行文字が足りなくなるまで繰り返します。

sed -e '
  y/ /\n/
  :a
    s/\n/ /
    s//\t/
  t a
' your_file.input

Perlでも同様です。

perl -lpe '
  s/ /$|--?"\t":$&/eg;
  $|-- unless $|--;
' your_file.input

perl -sF'\x20' -lane '
  splice @F, $_, 2, "@F[$_,$_+1]" for 0 .. (@F>>1)-1;
  print @F;
' -- -,=$'\t' your_file.input
```

関連情報