sed:保持模式和重新排列

hio*_*iob 4 regex variables awk sed

我不确定我是否可以用sed完全做到这一点:

我想重新排列这样的线条

GF:001,GF:00012,GF:01223<TAB>XXR
GF:001,GF:00012,GF:01223,GF:0666<TAB>XXXR3
Run Code Online (Sandbox Code Playgroud)

GF:001<TAB>XXR
GF:00012<TAB>XXR
GF:01223<TAB>XXR
GF:001<TAB>XXXR3
GF:00012<TAB>XXXR3
GF:01223<TAB>XXXR3
GF:0666<TAB>XXXR3
Run Code Online (Sandbox Code Playgroud)

任何提示?GF:XXXX的基数是GF:XXXX的长度.

我坚持,sed -n ' '/\(XX.*\)$/' { s/,/\t\1\n/ }' input但我不能首先引用最初匹配的模式.有任何想法吗?干杯!

更新:我认为仅使用sed是不可能的.所以我使用perl来做到这一点:

perl -e 'open(IN, "< file");
while (<IN>) {
    @a = split(/\t/);
    @gos = split(/,/, $a[0]);
    foreach (@gos) {
      print $_."\t".$a[1];
    }
close( IN );' > output
Run Code Online (Sandbox Code Playgroud)

但是,如果有人知道解决这个问题的方法,sed请在这里发布...

Jon*_*ler 7

sed虽然我可能会使用Perl(或Awk或Python)来完成它,但它可以完成.

我声称这种解决方案没有优雅,但蛮力和无知有时会得到回报.我创建了一个名为unordiginally的文件,sed.script其中包含:

/\(GF:[0-9]*\),\(.*\)<TAB>\(.*\)/{
:redo
s/\(GF:[0-9]*\),\(.*\)<TAB>\(.*\)/\1<TAB>\3@@@@@\2<TAB>\3/
h
s/@@@@@.*//
p
x
s/.*@@@@@//
t redo
d
}
Run Code Online (Sandbox Code Playgroud)

我把它当作:

sed -f sed.script input
Run Code Online (Sandbox Code Playgroud)

其中input包含问题中显示的两行.它产生了输出:

GF:001<TAB>XXR
GF:00012<TAB>XXR
GF:01223<TAB>XXR
GF:001<TAB>XXXR3
GF:00012<TAB>XXXR3
GF:01223<TAB>XXXR3
GF:0666<TAB>XXXR3
Run Code Online (Sandbox Code Playgroud)

(我冒昧故意误解<TAB>为5个字符的序列而不是单个制表符;您可以轻松修复答案以处理实际的制表符.)

sed脚本说明:

  • 查找具有多个GF:nnn以逗号分隔的行的行(我们不需要处理包含单个此类事件的行).只在这样的行上执行脚本的其余部分.其他任何东西都通过(打印)不变.
  • 创建一个标签,以便我们可以分支回来
  • 将线分成3个记忆部分.第一部分是最初的GF信息; 第二部分是任何其他GF信息; 第三部分是之后的领域<TAB>.将其替换为第一个字段,<TAB>第三个字段,难以置信的标记图案(@@@@@),第二个字段<TAB>,第三个字段.
  • 将修改后的行复制到保留空间.
  • 删除标记图案到最后.
  • 打印.
  • 将保持空间交换到模式空间.
  • 删除所有内容,包括标记图案.
  • 如果我们做了任何工作,请回到redo标签上.
  • 删除剩下的内容(已经打印).
  • 脚本块结束.

这是一个简单的循环,可以在每次迭代时将模式数减少一个.