Tricks on handling multiple line inputs and outputs
There are some of the trivial bag of tricks that I don’t normally take notice, which does often comes back to bother me. I just have to trip on Finagle’s Law whenever I forget these tricks after long disuse. Things like handling multi-line inputs and outputs seems to fit into that category, so here’s all I can recall form my own reference:
Printing multiple line outputs with a single echo command
The special escape for newline in bash is $'\n'
. Here’s an example how
it’s being used:
% echo "Hello$'\n'World"
Hello
World
Other non-printable characters can be similarly escaped this way (e.g.
The NUL
terminator represented by $'\0'
).
Reading multi-line inputs from stdin
This is achieved by using the <<
operator:
% cat <<TEST
> This is a test
> Hello World
> TEST
This is a test
Hello World
Reading multi-lines of a file into a single variable
Because spaces are treated as field separators in bash, and it won’t try
to read past the first separator, you need to force the shell to treat
nothing as a separator, by modifying the IFS
(Input Field
Separator):
OLDIFS=$IFS IFS= var=($(< filename.txt)) IFS=$OLDIFS
This above example assumes that you have a file called filename.txt
,
and at the end of the operation, the entire contents of the file is
stored in the var
variable.
Matching multiple lines using grep
When searching for two or more consecutive words within a sentence on a
text file (or HTML), sometimes it is possible that the words are span
across multiple lines, hence making typical word search, barring from
using a script, difficult. One of the neat tricks to accomplish this
without using any script, is through GNU grep’s -P
flag.
Assuming that you have a file called test.txt
that spans two or more
lines:
I like to say a nice warm "Hello
World" to all of you out there!
To search for the consecutive words “Hello World”:
grep -P "Hello\WWorld" test.txt
Curiously, it does not seem to work on Gentoo/Ubuntu linux’s version of
grep
but works only on my old RedHat distro only. Maybe it’s something
that has been phased out.
Splitting inputs into multiple lines
The easiest way to split things on the command line is to use the
sed
command:
% echo "Hello World" | sed -e 's/ /\n/'
Hello
World
If you want to do this within vim, it is a little bit less straightforward but still doable:
:s/ /<CTRL-V><ENTER>/
Replace the items in the angled-braces with the actual keystroke itself. The screen the output actually looks like:
:s/ /^M/
So don’t be concerned by the visual difference.