如果一行的长度小于数字,请附加到其前一行

时间:2019-02-09 02:47:27

标签: bash

我有一个看起来像这样的文件:

ABCDEFGH
ABCDEFGH
ABC
ABCDEFGH
ABCDEFGH
ABCD
ABCDEFGH

大多数行的固定长度为8。但是,它们之间的某些行的长度小于8。我需要一条简单的代码行,将每条短行附加到其前一行。

我尝试了以下代码,但是在处理大文件时会占用大量内存。

cat FILENAME | awk 'BEGIN{OFS=FS="\t"}{print length($1), $1}' | tr 
'\n' '\t' | sed 's/8/\n/g' | awk 'BEGIN{OFS="";FS="\t"}{print $2, $4}'

我期望的输出:

ABCDEFGH
ABCDEFGHABC
ABCDEFGH
ABCDEFGHABCD
ABCDEFGH

4 个答案:

答案 0 :(得分:4)

如果您选择perl,请尝试:

perl -0777 -pe 's/(\n)(.{1,7})$/\2/mg' filename
  • -0777选项告诉perl吞下所有行。
  • 模式(\n)(.{1,7})与长度小于8的行匹配,将\1分配给换行,将\2分配给字符串。
  • 替换\2不包含前面的换行符,并附加到前面的行。

答案 1 :(得分:1)

Service
  • WorkManager-将下一行附加到图案空间
  • sed <FILENAME 'N;/\n.\{8\}/!s/\n//;P;D' -第二行是否包含8个字符?
    • N;-否:将这两行合并在一起
  • /\n.\{8\}/-打印图案空间的第一行
  • !s/\n//;-删除模式空间的第一行,开始下一个循环

答案 2 :(得分:1)

不带\n的默认打印,当当前行的长度为8时,将其附加到最后一行。 第一行和最后一行是特殊的。

awk 'NR==1 {printf $0;next} 
     length($0)==8 {printf "\n"}
     {printf("%s",$0)}
     END { printf "\n" }' FILENAME

拥有GNU sed 4.2(支持-z选项)时,您可以尝试
编辑(见评论)

sed -rz 's/\n(.{0,7})\n/\1\n/g' FILENAME

答案 3 :(得分:0)

如果您喜欢旧的传统工具,则可以使用ed, the standard text editor

printf '%s\n' 'g/^.\{,7\}$/-,.j' wq | ed -s filename