如何用空格分隔字符(数字)序列

如何用空格分隔字符(数字)序列

我有这样的情况:

my data:

ID01 120120101
ID02 101010101
ID03 210210210
ID04 505052120

我想要这些数据:output

ID01 1 2 0 1 2 0 1 0 1
ID02 1 0 1 0 1 0 1 0 1
ID03 2 1 0 2 1 0 2 1 0
ID04 5 0 5 0 5 2 1 2 0

所以,我想分隔第二列中出现的所有数字(我的数据),但第一根柱必须保持完整。

为此,我尝试创建两个文件:一个具有 ID ($1-file1),另一个具有我想要用空格分隔的序列 (file2)。我尝试后:

sed -i -- 's//\t/g' file2

但我收到以下错误:

sed: -e expression #1, char 0: no previous regular expression

我该如何解决这个问题?

答案1

怎么样

perl -alne 'print join " ", $F[0], split("", $F[1])' data
ID01 1 2 0 1 2 0 1 0 1
ID02 1 0 1 0 1 0 1 0 1
ID03 2 1 0 2 1 0 2 1 0
ID04 5 0 5 0 5 2 1 2 0

如果您想要(完全)制表符分隔的输出,请更改为

perl -alne 'print join "\t", $F[0], split("", $F[1])' data

或者如果您想在ID第二个字段的数字后面保留一个制表符,但用空格分隔,

perl -alne 'print join "\t", $F[0], join " ", split("", $F[1])' data

答案2

在 中sed,空正则表达式意味着重用前一个正则表达式,在本例中您没有。如果您将列分开,您可以执行以下操作:

sed 's/./& /g' file2

(匹配任何字符,然后替换回我们与 匹配的任何字符&,并添加空格。)

但仅更改第二列更容易awk

awk '{gsub(/./, "& ", $2)} 1' data 

gsub与 sed 中的几乎相同s///g。据我测试,awk确实支持空正则表达式,但这会增加一个额外的空格,因为它也在第一个数字之前匹配。 (嗯,上面还在末尾添加了一个额外的空格。)

答案3

它并不漂亮,但很有效

cat my_data | sed -e 's/./ &/g' -e 's/^ \(.\) \(.\) \(.\) \(.\)  /\1\2\3\4/'

第一个表达式在所有字母之前放置一个空格。接下来删除第一部分中的空格。

您还可以编写脚本:

#! /bin/bash
while read ID NUMBERS; do
    echo $ID$(echo $NUMBERS | sed -e 's/./ &/g')
done

然后运行

cat my_data | ./my_script

答案4

当您无法使用s带有标志的命令时,一种方法是在带有该命令的循环中g使用该命令(以后续条件为条件的跳转)。sts

这里:

sed -e :1 -e 's/\([^ ]\)\([^ ]\{1,\}\)$/\1 \2/;t1'

即用该非空格、一个空格和该非空格序列替换行末尾的一个非空格,后跟一系列 1 个或多个非空格,然后重复,直到无法替换为止。所以对于每一行,它都是这样的(这里是第一行):

ID01 120120101
-> ID01 1 20120101
-> ID01 1 2 0120101
-> ID01 1 2 0 120101
-> ID01 1 2 0 1 20101
-> ID01 1 2 0 1 2 0101
-> ID01 1 2 0 1 2 0 101
-> ID01 1 2 0 1 2 0 1 01
-> ID01 1 2 0 1 2 0 1 0 1
at this point the "s" command fails, so "t1" doesn't branch

perl

perl -pe 's/\S+$/join " ", split "", $&/e'

相关内容