将短行移动到上一行

move short lines to previous line

我想将短行(比方说短于 60 个字符)移动到上一行。

有一个类似的问题:move line which matches pattern to previous line

但是对于我短线的情况是不行的

我可以得到所有的短线,像这样:awk 'NF<60' FS= file.

但我想将它们移到上一行。

下面是我想要的示例。 较短的行由“abc”表示(长度 < 4)。

之前:

123456789
abc
123456789
123456789
123456789
abc
abc
123456789
123456789
abc
abc
abc
123456789
123456789
abc
123456789
123456789

之后:

123456789abc
123456789
123456789
123456789abcabc
123456789
123456789abcabcabc
123456789
123456789abc
123456789
123456789

这是 awk 的一种方式。它会延迟打印直到看到下一行。
设置 FS="" 适用于 gawk 4.2.1 及更高版本和 mawk 1.3.4 20200120.
“原始”awk 版本 20121220 失败。(感谢@Ed Morton 的提醒!)。其他版本未测试。

% awk -F '' 'NR==1{ line=[=10=]; next }
             NF<=60{ prev=[=10=]; printf("%s%s",line,prev); line=""; next }
             NF>60{ print line } { line=[=10=] }
             END{ print line }' file
1 ewf nwje fwkjef wkejf wkej fwkejf wkejfwkjef woief nowienfw2 owenuof wuoef wue fiwuf wiuenf wie
3 ewf nwje fwkjef wkejf wkej fwkejf wkejfwkjef woief nowienfw
4 ewf nwje fwkjef wkejf wkej fwkejf wkejfwkjef woief nowienfw5 owenuof wuoef wue fiwuf wiuenf wie6 owenuof wuoef wue fiwuf wiuenf wie
7 ewf nwje fwkjef wkejf wkej fwkejf wkejfwkjef woief nowienfw
8 ewf nwje fwkjef wkejf wkej fwkejf wkejfwkjef woief nowienfw

使用“原始”awk 使用length()

% oawk 'NR==1{ line=[=11=]; next }
        length([=11=])<=60{ prev=[=11=]; printf("%s%s",line,prev); line=""; next }
        length([=11=])>60{ print line } { line=[=11=] }
        END{ print line }' file  
1 ewf nwje fwkjef wkejf wkej fwkejf wkejfwkjef woief nowienfw2 owenuof wuoef wue fiwuf wiuenf wie
3 ewf nwje fwkjef wkejf wkej fwkejf wkejfwkjef woief nowienfw
4 ewf nwje fwkjef wkejf wkej fwkejf wkejfwkjef woief nowienfw5 owenuof wuoef wue fiwuf wiuenf wie6 owenuof wuoef wue fiwuf wiuenf wie
7 ewf nwje fwkjef wkejf wkej fwkejf wkejfwkjef woief nowienfw
8 ewf nwje fwkjef wkejf wkej fwkejf wkejfwkjef woief nowienfw

数据

% cat file
1 ewf nwje fwkjef wkejf wkej fwkejf wkejfwkjef woief nowienfw
2 owenuof wuoef wue fiwuf wiuenf wie
3 ewf nwje fwkjef wkejf wkej fwkejf wkejfwkjef woief nowienfw
4 ewf nwje fwkjef wkejf wkej fwkejf wkejfwkjef woief nowienfw
5 owenuof wuoef wue fiwuf wiuenf wie
6 owenuof wuoef wue fiwuf wiuenf wie
7 ewf nwje fwkjef wkejf wkej fwkejf wkejfwkjef woief nowienfw
8 ewf nwje fwkjef wkejf wkej fwkejf wkejfwkjef woief nowienfw
$ cat tst.awk
length([=10=]) < 4 {
    out = out [=10=]
    next
}
{
    if ( out != "" ) {
        print out
    }
    out = [=10=]
}
END {
    print out
}

$ awk -f tst.awk file
123456789abc
123456789
123456789
123456789abcabc
123456789
123456789abcabcabc
123456789
123456789abc
123456789
123456789
perl -0pe 's/\n([^\n]{1,6}(?=\n))//g' file 

-0perl 置于“slurp”模式,-p 告诉 perl 在处理后打印每条记录。 -e 指定下一个参数是 运行 的程序。该程序只是进行搜索和替换,寻找长度小于(在本例中)6 个字符的“行”(运行 非换行符)。需要正前瞻 ((?=)) 来处理连续的短线。

您可以使用类似以下内容轻松参数化行长度:

 perl -s0pe 's/\n([^\n]{1,$len}(?=\n))//g' -- -len=60 input

这可能对你有用 (GNU sed):

sed -E ':a;N;/\n.{4}/!s/\n//;ta;P;D' file

在整个文件中打开两行 window。

如果第二行没有 4 个(您可以根据需要将其更改为 60 个)或更多字符,请删除换行符,追加下一行并再次检查。

否则,print/delete 第一行并重复。

N.B。 NPD 命令有点特殊,阅读它们 here