bash 向标准输出添加空格

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3286615/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 22:21:24  来源:igfitidea点击:

Adding spaces to stdout

bash

提问by kolrie

Is it possible to add spaces to the left of every output to stdout (and stderr if possible) when I run commands in a bash shell script?

当我在 bash shell 脚本中运行命令时,是否可以在每个输出的左侧添加空格到 stdout(如果可能,还有 stderr)?

I'd like to do something like:

我想做类似的事情:

#!/bin/bash
echo Installing: Something
echo "    => installing prerequisite1"

## INSERT MAGICAL LEFT SPACES COMMAND HERE ##

apt-get install -q -y prerequisite

## ANOTHER MAGICAL CANCELLING LEFT SPACES COMMAND HERE ##

echo "    => installing prerequisite2"
# ... the padding again ...
wget http://abc.com/lostzilla.tar.gz
tar vzxf lostzilla.tar.gz
cd lostzilla-1.01
./configure
make && make install
# ... end of padding ...

echo Done.

Any idea?

任何的想法?

EDIT:Added quotes to the echo command, otherwise they won't be padded.

编辑:在 echo 命令中添加了引号,否则它们将不会被填充。

回答by paxdiablo

Yes, you can quote them for simple things:

是的,您可以为简单的事情引用它们:

echo '    => installing prerequisite1'

and pipe the output through sedfor complex things:

并通过管道将输出sed用于复杂的事情:

tar vzxf lostzilla.tar.gz 2>&1 | sed 's/^/   /'

The 2>&1puts stdout and stderr onto the stdout stream and the sedreplaces every start-of-line marker with three spaces.

2>&1放输出和错误到标准输出流和sed开始的行每标记用三个空格代替。

How well this will work on something like wgetwhich does all sorts of cursor manipulations I'm not sure.

这在诸如wget执行各种光标操作之类的事情上的效果如何,我不确定。

Example shown here:

此处显示的示例:

pax> ls -1 p*
phase1.py
phase1.sh
phase2.py
phase2.sh
primes.c
primes.exe
primes.sh
primes.stat

pax> ls -1 p* | sed 's/^/   /'
   phase1.py
   phase1.sh
   phase2.py
   phase2.sh
   primes.c
   primes.exe
   primes.sh
   primes.stat

One trick I've used in the past is to ensure that the scripts themselves take care of the indentation:

我过去使用的一个技巧是确保脚本本身处理缩进:

#!/bin/bash
if [[ "${DONT_EVER_SET_THIS_VAR}" = "" ]] ; then
        export DONT_EVER_SET_THIS_VAR=except_for_here
        
#!/usr/bin/gawk -f

/^#SPACEON/ { spaces=1; }
/^#SPACEOFF/ { spaces=0; }
!/^#SPACE/ { 
    if(spaces) {
        print "    " 
#!/bin/bash

echo Installing: Something
echo '=> installing prerequisite1'

echo '#SPACEON'

echo You would see apt-get install -q -y prerequisite

echo '#SPACEOFF'
echo '=> installing prerequisite2'
echo '#SPACEON'


echo You would see wget http://abc.com/lostzilla.tar.gz
echo You would see tar vzxf lostzilla.tar.gz
echo You would see cd lostzilla-1.01
echo You would see ./configure
echo You would see make \&\& make install

echo '#SPACEOFF'
echo Done.
; } else { print
$ ./do-stuff | ./magic-spacing 
Installing: Something
=> installing prerequisite1
    You would see apt-get install -q -y prerequisite
=> installing prerequisite2
    You would see wget http://abc.com/lostzilla.tar.gz
    You would see tar vzxf lostzilla.tar.gz
    You would see cd lostzilla-1.01
    You would see ./configure
    You would see make && make install
Done.
; } }
| sed 's/^/ /' exit fi ls -1 p*

This will re-run the script with indentation through sedif it's not already doing so. That way, you don't have to worry about changing all your output statements. A bit of a hack, I know, but I tend to just do what's necessary for quick-and-dirty shell scripts.

sed如果它还没有这样做,这将重新运行带有缩进的脚本。这样,您就不必担心更改所有输出语句。我知道有点小技巧,但我倾向于只为快速而肮脏的 shell 脚本做必要的事情。

回答by bstpierre

If you want to turn spacing on and off, use the following awk script:

如果要打开和关闭间距,请使用以下 awk 脚本:

$ echo -e 'hello\nworld' | awk '{print "    ",
# space padding for single string
printf "%-4s%s\n" "" "=> installing prerequisite1"

# space padding for single command output
# use of subshell leaves original IFS intact
( IFS=$'\n'; printf "    %s\n" $(command ls -ld * 2>&1) )

# note: output to stderr is unbuffered
( IFS=$'\n'; printf "    %s\n" $(command ls -ld * 1>&2) )
}' hello world

Note that there are slight problems with your bash scipt. Notably, the use of =>in your echo statements will output the character =to the file "installing".

请注意,您的 bash 脚本存在一些小问题。值得注意的是,=>在 echo 语句中使用 会将字符输出=到文件“安装”中。

{
cmd1 1>&2
cmd2 1>&2
cmd3 1>&2
} 2>&1 | sed 's/.*/    &/'

Combining the two gives me:

将两者结合起来给我:

( 
exec 1>&2
command ls -ld * 
) 2>&1 | sed 's/^/    /'

Where do-stuff is your bash script and magic-spacing is my awk script above.

do-stuff 是你的 bash 脚本,magic-spacing 是我上面的 awk 脚本。

回答by Mark Rushakoff

Depending on how the command writes to stdout, you can just indent with a simple awk script:

根据命令写入标准输出的方式,您可以使用简单的 awk 脚本缩进:

ls -ld | pyp "'    '+p"

回答by yabt

Quite un-magical you can use printf to do the following:

您可以使用 printf 执行以下操作,这很不神奇:

##代码##

It's also possible to group commands by enclosing them in curly braces and space-padd their output like so:

也可以通过将命令括在花括号中并对它们的输出进行空格填充来对命令进行分组,如下所示:

##代码##

回答by tom

It's possible to redirect stdout to stderr script/shell-wide using exec ...

可以使用 exec ... 将 stdout 重定向到 stderr 脚本/shell 范围内

##代码##

回答by Pieter

Use python pyp (The Pyed Piper):

使用 python pyp (The Pyed Piper):

##代码##