假设我有一个标准的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或类似的文件中,这样会使输出缩进。
答案 0 :(得分:2)
为此,我将使用awk。
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