将每条线分成相等的部分

时间:2012-09-27 16:30:16

标签: sed awk

如果有人能建议我使用命令(sed或AWK一行命令)将每行文件分成相同数量的部分,我会很高兴。例如,将每一行划分为4个部分。

输入:

ATGCATHLMNPHLNTPLML

输出:

ATGCA THLMN PHLNT PLML

4 个答案:

答案 0 :(得分:1)

这应该可以使用GNU sed:

sed -r 's/(.{4})/\1 /g'
  • -r需要使用扩展正则表达式
  • .{4}捕获每四个字符
  • \1是指被括号( )包围并在该群组后面添加空格的捕获组
  • g确保在每一行上尽可能多地进行替换

测试;这是我终端的输入和输出:

$ echo "ATGCATHLMNPHLNTPLML" | sed -r 's/(.{4})/\1 /g'
ATGC ATHL MNPH LNTP LML

答案 1 :(得分:1)

我怀疑awk不是最好的工具,但是:

gawk --posix '{ l = sprintf( "%d", 1 + (length()-1)/4);
    gsub( ".{"l"}", "& " ) } 1' input-file

如果你有一个符合posix标准的awk你可以省略--posix,但是-posix对于gnu awk是必要的,因为这似乎是我用gawk提供解决方案的最常用的实现。< / p>

答案 2 :(得分:0)

perl的

perl可能是更好的选择:

export cols=4
perl -ne 'chomp; $fw = 1 + int length()/$ENV{cols}; while(/(.{1,$fw})/gm) { print $1 . " " } print "\n"'

这会重新计算每一行的字段宽度。

的coreutils

GNU coreutils替代方案,根据infile的第一行选择字段宽度:

cols=4
len=$(( $(head -n1 infile | wc -c) - 1 ))
fw=$(echo "scale=0; 1 + $len / 4" | bc)

cut_arg=$(paste -d- <(seq 1 $fw 19) <(seq $fw $fw $len) | head -c-1 | tr '\n' ',')

cut_arg的值在上述情况中:

1-5,6-10,11-15,16-

现在将线切成适当的块:

cut --output-delimiter=' ' -c $cut_arg infile

答案 3 :(得分:0)

这可能适合你(GNU sed):

sed 'h;s/./X/g;s/^\(.*\)\1\1\1/\1 \1 \1 \1/;G;s/\n/&&/;:a;/^\n/bb;/^ /s/ \(.*\n.*\)\n\(.\)/\1 \n\2/;ta;s/^.\(.*\n.*\)\n\(.\)/\1\2\n/;ta;:b;s/\n//g' file

说明:

  • h将模式空间(PS)复制到保留空间(HS)
  • s/./X/g用相同的非空格字符替换HS中的每个字符(在本例中为X
  • s/^\(.*\)\1\1\1/\1 \1 \1 \1/将该行分为4个部分(空格分隔)
  • G追加换行符后跟HS的内容到PS
  • s/\n/&&/加倍换行符(稍后用作标记)
  • :a引入了一个循环命名空间
  • /^\n/bb如果我们到达换行符,我们就完成了并转移到b命名空间
  • /^ /s/ \(.*\n.*\)\n\(.\)/\1 \n\2/;ta;如果第一个字符是空格,此时在实线上添加一个空格并重复
  • s/^.\(.*\n.*\)\n\(.\)/\1\2\n/;ta任何其他角色只是碰撞并重复
  • :b;s/\n//g所有操作只需删除标记并打印出结果

对于任何行长度的这项工作,但是该行不能完全被4整除,最后一部分也将包含余数。