每隔一列添加选项卡

Jas*_*ark 3 bash text-processing

该文件如下(所有空格都是“单空格”):

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
Run Code Online (Sandbox Code Playgroud)

我需要的是将每隔一列(偶数编号的字段)之后的空格替换为制表符 ( \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
Run Code Online (Sandbox Code Playgroud)

由于我的原始文件有更多的列数,所以命令行不应该是手动的 (指定一定数量的字段)。

我想请教大家这个问题。

预先感谢您的帮助。

cho*_*oba 9

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

sed -E 's/( [^ ]*) /\1\t/g'
Run Code Online (Sandbox Code Playgroud)


Adm*_*Bee 5

awk基于强制性的解决方案 ;) :

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

这将遍历所有字段并通过 打印它们printf,其中字段内容后跟

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


Kus*_*nda 5

简短而愚蠢的方式,但完全合法,假设我们知道我们正在处理 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
Run Code Online (Sandbox Code Playgroud)

这将用换行符替换每个原始空格分隔符。然后它读取结果流(每行一个字段)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
Run Code Online (Sandbox Code Playgroud)

该代码临时将空格分隔的字段对存储在数组中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
}
Run Code Online (Sandbox Code Playgroud)