繁体   English   中英

如何使用unix命令将字符串拆分为具有特定宽度的行? 当输入字符串是无限的?

[英]How can I split string to lines with specific width using unix commands? When the input string is infinite?

我想转换

Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He...

Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He
llo.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hell
o.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.
Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He
...,

其中宽度为80个字符。

我首先想到我可以使用sed (让我用5字符来解释,而不是80字符来澄清。)

echo "longlonglonglonglonglonglonglonglonglonglonglong" | sed 's/\(.\{5\}\)/\1\'$'\n/g'

longl
onglo
nglon
glong
longl
onglo
nglon
glong
longl
ong

我想要的。 但是,当输入字符串永远持续时,我无法使用这种方式。

while true; do; echo -n "Hello."; done | sed 's/\(.\{5\}\)/\1\'$'\n/g'

上面的命令不起作用。 我也试过使用perl ,但是徒劳无功。 perl -pe 's/(.{5})/$1\\n/g' )所以我放弃了在unix命令中解决并在C中写了一个小程序。

#include <stdio.h>
int main(int argc, char *argv[]) {
  int i = 0, ch;
  while ((ch = fgetc(stdin)) != EOF) {
    putchar((char)ch);
    i += 1;
    if (ch == '\n') {
      i = 0;
    }
    if (i >= 80) {
      printf("\n");
      i = 0;
    }
  }
  return 0;
}

该程序对我很好。 所以问题是,如何使用unix命令将长的(可能是无限的)输入字符串拆分成行?

fold可以成为你的朋友:

$ fold -w 80 file
Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He
llo.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hell
o.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.
Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He
...

$ fold -w 20 file
Hello.Hello.Hello.He
llo.Hello.Hello.Hell
o.Hello.Hello.Hello.
Hello.Hello.Hello.He
llo.Hello.Hello.Hell
o.Hello.Hello.Hello.
Hello.Hello.Hello.He
llo.Hello.Hello.Hell
o.Hello.Hello.Hello.
Hello.Hello.Hello.He
llo.Hello.Hello.Hell
o.Hello.Hello.Hello.
Hello.Hello.Hello.He
llo.Hello.Hello.Hell
o.Hello.Hello.Hello.
Hello.Hello.Hello.He
...

man fold

fold - 将每个输入行换行以适合指定的宽度

-w , - width = WIDTH

使用WIDTH列而不是80

所以实际上fold filefold -w 80 file相同

你可以使用perl one liner,

perl -lpe 'BEGIN{ $/ = \80 }' file

来自peldoc perlvar

$ /

输入记录分隔符,默认为换行符。 [..]将$ /设置对整数的引用,包含整数的标量或可转换为整数的标量将尝试读取记录而不是行,最大记录大小为引用的整数字符数

您也可以尝试以下perl代码,

$ perl -0777pe 's/(.{80})/\1\n/g' file
Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He
llo.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hell
o.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.
Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He
...

尝试选项-u

-u( - unbuffered)

尽可能减少输入和输出的缓冲。 (如果输入来自'tail -f'之类,并且您希望尽快看到转换后的输出,则此功能特别有用。)

sed -u 's/\(.\{5\}\)/\1\'$'\n/g'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM