我有一个制表符分隔的文件,其中每一行都有:
K00001;K00004;K00008 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
我想要一行具有唯一的代码和相同的数字序列,如下所示:
K00001 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00004 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00008 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
答案1
您可以使用 awk 拆分第一列:
~$ awk '{split($1,a,";"); $1="";for (i in a){print a[i],$0}}' myfile
K00001 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00004 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00008 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
;
您在( )上拆分第一列split($1,a,";")
,然后将其删除,以打印$0
数组中每个项目的整个(新)行 ( )。
正如评论中所建议的,编辑后,我们可以看到制表符用作分隔符。要使用 tab 作为输出字段分隔符,您可以使用OFS="\t"
,例如在BEGIN
awk 的部分。此外,还用 插入一个空字段$1=""
。因此,与其打印a[i]
then $0
,不如设置$1
为a[i]
then print $0
:
~$ awk 'BEGIN{OFS="\t"}{split($1,a,";"); for (i in a){$1=a[i];print}}' myfile
K00001 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00004 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00008 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
答案2
这应该做你想做的。基本上,我们通过拆分并将拆分限制为第一个字段来放入第一个字段(键)$k
和其余字段。然后我们将键分开并在其自己的行上打印每个键以及其余字段。$f
\t
2
;
perl -nle '($k, $f) = split "\t", $_, 2; print "$_\t$f" for split ";", $k'
-n
循环输入。您可以通过管道将文件传输到 perl,也可以在命令行末尾传递输入文件的名称。-l
启用自动行结束管理。
答案3
和sed
:
sed 's/^\([^[:blank:];]*\);\([^[:blank:]]*\)\(.*\)/\1\3\
\2\3/;P;D'
答案4
另一种 Perl 语句。
$ perl -pe 's/^([^;]+);([^;]+);(\S+)\s+(.*)/$1 $4\n$2 $4\n$3 $4/' file
K00001 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00004 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00008 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
另一个 sed 单行代码。
$ sed 's/^\([^;]\+\);\([^;]\+\);\([^ ]\+\) \+\(.*\)/\1 \4\n\2 \4\n\3 \4/' file
K00001 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00004 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0
K00008 0 0 34 0 0 0 0 0 0 0 0 0 0 0 0 0 36 0 0 52 0 0 0 6 0