将多行中的相应字符粘贴在一起

时间:2015-01-06 14:46:03

标签: linux bash

我正在编写一个linux命令,它将来自多行的相应字符粘在一起。例如:我想更改这些行

A---
-B--
---C
--D-

到此:

A----B-----D--C-

到目前为止,我已经做到了:

cat sanger.a sanger.c sanger.g sanger.t | cut -c 1

这只适用于第一列,但它必须适用于所有列。

有没有人可以提供帮助?

编辑:这是一个更好的例子。我想要这个:

  

SUGAR

     

HONEY

     

糖果

成为

  

SHC UOA GND AED RYY(无空格)

3 个答案:

答案 0 :(得分:1)

更新规格的awk方式

awk -vFS= '{for(i=1;i<=NF;i++)a[i]=a[i]$i}
           END{for(i=1;i<=NF;i++)printf "%s",a[i];print ""}' file

输出

A----B-----D--C-

SHCUOAGNNAEDRYY

对于大文件的P.s这将使用大量内存

一种不使用awk的可怕方式,你需要事先知道字段的数量。

for i in {1..4};do cut -c $i test | tr -d "\n" ; done;echo

答案 1 :(得分:1)

这是一个没有awksed的解决方案,假设文件名为f

paste -s -d "" <(for i in $(seq 1 $(wc -L < f)); do cut -c $i f; done)

wc -L是一个GNUism,它返回输入文件中最长行的长度,根据您的版本/语言环境,这可能不起作用。您可以通过执行以下操作找到最长的行:

awk '{if (length > x) {x = length}} END {print x}' f

然后在seq命令中使用此值而不是上面的命令替换。

答案 2 :(得分:0)

好吧,是时候疯狂了! :D

免责声明:如果这是严重的事情,请使用比此更脆弱的东西。 awk浮现在脑海中。除非你对你的sed能力有足够的信心来维持这种疯狂。

cat file1 file2 etc | sed -n '1h; 1!H; $ { :loop; g; s/$/\n/; s/\([^\n]\)[^\n]*\n/\1/g; p; g; s/^.//; s/\n./\n/g; h; /[^\n]/ b loop }' | tr -d '\n'; echo

这有三个部分:假设您有一个文件foo.txt

12345
67890
abcde
fghij

然后

cat foo.txt | sed -n '1h; 1!H; $ { :loop; g; s/$/\n/; s/\([^\n]\)[^\n]*\n/\1/g; p; g; s/^.//; s/\n./\n/g; h; /[^\n]/ b loop }'

产生

16af
27bg
38ch
49di
50ej

之后,tr -d '\n'删除换行符,;echo在最后添加一行。

这种疯狂的核心是sed代码,这是

1h
1!H
$ {
  :loop
  g
  s/$/\n/
  s/\([^\n]\)[^\n]*\n/\1/g
  p
  g
  s/^.//
  s/\n./\n/g
  h
  /[^\n]/ b loop
}

这首先遵循基本模式

1h          # if this is the first line, put it in the hold buffer
1!H         # if it is not the first line, append it to the hold buffer
$ {         # if this is the last line, 
  do stuff  # do stuff. The whole input is in the hold buffer here.
}

在处理之前汇总保持缓冲区中的所有输入。一旦整个输入都在保持缓冲区中,就会发生这种情况:

  :loop
  g                         # copy the hold buffer to the pattern space
  s/$/\n/                   # put a newline at the end
  s/\([^\n]\)[^\n]*\n/\1/g  # replace every line with only its first character
  p                         # print that
  g                         # get the hold buffer again
  s/^.//                    # remove the first character from the first line
  s/\n./\n/g                # remove the first character from all other lines
  h                         # put that back in the hold buffer
  /[^\n]/ b loop            # if there's something left other than newlines, loop

你有它。我可能只是召唤了克苏鲁。