缩进长行标准输出

时间:2019-05-03 08:56:20

标签: bash awk sed stdout interactive

假设我有一个标准的80列终端,执行带有长行输出(即来自ls的stdout)的命令,该命令分为两行或更多行,并且希望缩进我所有bash stdout的延续行。

缩进应该是可配置的,可以是1或2或3或任何空格。

从此

lrwxrwxrwx 1 root root 24 Feb 19 1970 sdcard -> /storage/emula
ted/legacy/

对此

lrwxrwxrwx 1 root root 24 Feb 19 1970 sdcard -> /storage/emula
ted/legacy/

阅读此Indenting multi-line output in a shell script,所以我尝试使用管道| sed 's/^/ /',但是却给出了完全相反的内容,使第一行缩进而不是连续。

理想情况下,每次打开交互式外壳程序并执行任何命令时,我都会将脚本放入profile.rc或类似的文件中,这样会使输出缩进。

3 个答案:

答案 0 :(得分:2)

为此,我将使用

awk -v width="$COLUMNS" -v spaces=4 '
BEGIN {
  pad = sprintf("%*s", spaces, "") # generate `spaces` spaces
}
NF {                               # if current line is not empty
  while (length > width) {         # while length of current line is greater than `width`
    print substr($0, 1, width)     # print `width` chars from the beginning of it
    $0 = pad substr($0, width + 1) # and leave `pad` + remaining chars
  }
  if ($0 != "")                    # if there are remaining chars
    print                          # print them too 
  next
} 1' file

一行:

awk -v w="$COLUMNS" -v s=4 'BEGIN{p=sprintf("%*s",s,"")} NF{while(length>w){print substr($0,1,w);$0=p substr($0,w+1)} if($0!="") print;next} 1'

正如@Mark在注释中建议的那样,您可以将其放入函数中并将其添加到.bashrc中,以方便使用。

function wrap() {
  awk -v w="$COLUMNS" -v s=4 'BEGIN{p=sprintf("%*s",s,"")} NF{while(length>w){print substr($0,1,w);$0=p substr($0,w+1)} if($0!="") print;next} 1'
}

用法:

ls -l | wrap

按要求由Ed Morton编辑:

与上面的oguzismails脚本非常相似,但应与Busybox或其他任何awk一起使用:

$ cat tst.awk
BEGIN { pad = sprintf("%" spaces "s","") }
{
    while ( length($0) > width ) {
        printf "%s", substr($0,1,width)
        $0 = substr($0,width+1)
        if ( $0 != "" ) {
            print ""
            $0 = pad $0
        }
    }
    print
}
$
$ echo '123456789012345678901234567890' | awk -v spaces=3 -v width=30 -f tst.awk
123456789012345678901234567890
$ echo '123456789012345678901234567890' | awk -v spaces=3 -v width=15 -f tst.awk
123456789012345
   678901234567
   890
$ echo '' | awk -v spaces=3 -v width=15 -f tst.awk

$

第一个测试用例是要显示在全角输入行之后没有打印出空白行,第三个测试用例是要显示它不删除空白行。通常我会使用sprintf("%*s",spaces,"")创建pad字符串,但在注释中看到这在您正在使用的非POSIX awk中不起作用。

答案 1 :(得分:1)

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

sed 's/./&\n  /80;P;D' file

这会将行拆分为长度80,并将后面的行缩进2个空格。

或者,如果您愿意:

s='  ' c=80
sed "s/./&\n$s/$c;P;D" file

要防止打印空行,请使用:

sed 's/./&\n/80;s/\n$//;s/\n    /;P;D' file

或更简单:

sed 's/./\n    &/81;P;D' file

答案 2 :(得分:0)

使用纯bash字符串操作的一种可能的解决方案。 您可以使脚本读取stdin并设置其格式。

MAX_LEN=5  # length of the first/longest line
IND_LEN=2  # number of indentation spaces
short_len="$((MAX_LEN-IND_LEN))"
while read line; do
    printf "${line:0:$MAX_LEN}\n"
    for i in $(seq $MAX_LEN $short_len ${#line}); do
        printf "%*s${line:$i:$short_len}\n" $IND_LEN
    done
done

用法:(假设脚本另存为indent.sh

$ echo '0123456789' | ./indent.sh
01234
  567
  89