向每隔一列添加选项卡

向每隔一列添加选项卡

文件如下(所有空格均为“单空格”):

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

我需要的是将每隔两列(偶数编号的字段)后面的空格替换为选项卡(\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

匹配两个空格,保留一个并替换第二个:

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,其中字段内容后跟

  • 到达最后一个字段时的“输出记录分隔符”(默认为换行符)
  • 否则,如果字段编号为奇数,则为空格,
  • \t如果字段编号为偶数,则为 a

答案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 列,其中包含交替的空格和制表符分隔符。


用于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来自的模块蟒蛇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 函数并行化两个或多个迭代器(在本例中为列表)。 Python 有一个紧凑的切片符号 [::2] 和 [1::2] 来引用给定列表中的偶数元素和奇数元素。在这里,我们从偶数 n 个奇数列表中各选择一个元素,并用空格将它们连接起来形成一对,然后连接这些对(又名,元组用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
```

相关内容