Indenting multi-line output in a shell script
Pipe it to sed
to insert 2 spaces at the beginning of each line.
git status | sed 's/^/ /'
Indent long line stdout
I'd use awk for this.
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
In one line:
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'
As @Mark suggested in comments, you can put this in a function and add it to .bashrc
for ease of use.
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'
}
Usage:
ls -l | wrap
Edit by Ed Morton per request:
Very similar to oguzismails script above but should work with Busybox or any other 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
$
That first test case is to show that you don't get a blank line printed after a full-width input line and the third is to show that it doesn't delete blank rows. Normally I'd have used sprintf("%*s",spaces,"")
to create the pad
string but I see in a comment that that doesn't work in the apparently non-POSIX awk you're using.
How to output a multiline string in Bash?
Here documents are often used for this purpose.
cat << EOF
usage: up [--level <n>| -n <levels>][--help][--version]
Report bugs to:
up home page:
EOF
They are supported in all Bourne-derived shells including all versions of Bash.
Multi-line string with extra space (preserved indentation)
Heredoc sounds more convenient for this purpose. It is used to send multiple commands to a command interpreter program like ex or cat
cat << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage
The string after <<
indicates where to stop.
To send these lines to a file, use:
cat > $FILE <<- EOM
Line 1.
Line 2.
EOM
You could also store these lines to a variable:
read -r -d '' VAR << EOM
This is line 1.
This is line 2.
Line 3.
EOM
This stores the lines to the variable named VAR
.
When printing, remember the quotes around the variable otherwise you won't see the newline characters.
echo "$VAR"
Even better, you can use indentation to make it stand out more in your code. This time just add a -
after <<
to stop the tabs from appearing.
read -r -d '' VAR <<- EOM
This is line 1.
This is line 2.
Line 3.
EOM
But then you must use tabs, not spaces, for indentation in your code.
Indenting read input when it contains multiple lines
It sounds like the issue is with the way read works. Read echos back keystrokes and I think perhaps because of stdout buffer it is writtern before the echo statements are flushed.
Using a combo of echo command and the -e
argument to read (interactive) fixes this in my testing.
#!/bin/bash
echo "Provide inputs:"
until [[ "$message" = "three" ]]; do
echo -ne "> "
read -e message
myArray+=($message) #Input added to array for later processing
done
Bash multi-line command with input | output
The reason for this happening to me was a unique issue I was having with my IDE .. It was inserting an actual character for a line break rather than just a physical line-break itself. The problem wasn't the syntax I was attempting, rather the inserted characters on save. Thanks to all who thoughtfully answered my question. My original un-escaped syntax was correct to begin with.
Capturing multiple line output into a Bash variable
Actually, RESULT contains what you want — to demonstrate:
echo "$RESULT"
What you show is what you get from:
echo $RESULT
As noted in the comments, the difference is that (1) the double-quoted version of the variable (echo "$RESULT"
) preserves internal spacing of the value exactly as it is represented in the variable — newlines, tabs, multiple blanks and all — whereas (2) the unquoted version (echo $RESULT
) replaces each sequence of one or more blanks, tabs and newlines with a single space. Thus (1) preserves the shape of the input variable, whereas (2) creates a potentially very long single line of output with 'words' separated by single spaces (where a 'word' is a sequence of non-whitespace characters; there needn't be any alphanumerics in any of the words).
Related Topics
How to Copy All PDF Files from a Directory and Its Subdirectories to One Location
Ansible Inside Script Command Not Found
Bash Script to Calculate Time Elapsed
How to Call Curl Without Using Server-Side Cache
Importing a Cmake Project into Eclipse Cdt
How to Add My Own Software to a Buildroot Linux Package
Maximum Resident Set Size Does Not Make Sense
How to Remove Jenkins Completely from Linux
How and When to Use /Dev/Shm for Efficiency
Escape Single Quotes in Shell Script
Count the Number of Executable Files in Bash
How to Move All Files Including Hidden Files into Parent Directory via *
Best Practices for Git Repositories on Open Source Projects
Sed Insert Line with Spaces to a Specific Line
Display Only Files and Folders That Are Symbolic Links in Tcsh or Bash