Here's one way using GNU awk
and rev
Run like:
awk -f ./script.awk <(echo "hello" | cowsay){,} | rev
Contents of script.awk
:
FNR==NR {
if (length > max) {
max = length
}
next
}
{
while (length < max) {
$0=$0 OFS
}
}1
Alternatively, here's the one-liner:
awk 'FNR==NR { if (length > max) max = length; next } { while (length < max) $0=$0 OFS }1' <(echo "hello" | cowsay){,} | rev
Results:
_______
> olleh <
-------
^__^ \
_______\)oo( \
\/\) \)__(
| w----||
|| ||
----------------------------------------------------------------------------------------------
Here's another way just using GNU awk
:
Run like:
awk -f ./script.awk <(echo "hello" | cowsay){,}
Contents of script.awk
:
BEGIN {
FS=""
}
FNR==NR {
if (length > max) {
max = length
}
next
}
{
while (length < max) {
$0=$0 OFS
}
for (i=NF; i>=1; i--) {
printf (i!=1) ? $i : $i ORS
}
}
Alternatively, here's the one-liner:
awk 'BEGIN { FS="" } FNR==NR { if (length > max) max = length; next } { while (length < max) $0=$0 OFS; for (i=NF; i>=1; i--) printf (i!=1) ? $i : $i ORS }' <(echo "hello" | cowsay){,}
Results:
_______
> olleh <
-------
^__^ \
_______\)oo( \
\/\) \)__(
| w----||
|| ||
----------------------------------------------------------------------------------------------
Explanation:
Here's an explanation of the second answer. I'm assuming a basic knowledge of awk
:
FS="" # set the file separator to read only a single character
# at a time.
FNR==NR { ... } # this returns true for only the first file in the argument
# list. Here, if the length of the line is greater than the
# variable 'max', then set 'max' to the length of the line.
# 'next' simply means consume the next line of input
while ... # So when we read the file for the second time, we loop
# through this file, adding OFS (output FS; which is simply
# a single space) to the end of each line until 'max' is
# reached. This pad's the file nicely.
for ... # then loop through the characters on each line in reverse.
# The printf statement is short for ... if the character is
# not at the first one, print it; else, print it and ORS.
# ORS is the output record separator and is a newline.
Some other things you may need to know:
The {,}
wildcard suffix is a shorthand for repeating the input file name twice.
Unfortunately, it's not standard Bourne shell. However, you could instead use:
<(echo "hello" | cowsay) <(echo "hello" | cowsay)
Also, in the first example, { ... }1
is short for { ... print $0 }
HTH.