Printing lines side by side in shell

Everybody knows, there is paste command in every *NIX to print two files side by side or join which is obviously used to join text-files by their key-fields. And there are a lot of examples and tutorials over Internet, so the subject is as trivial as cat-ting files together with right command-line options.

Ah, wait… What if we have textual data stored not in files but in two variables as a result, for example, of piping or redirection?

Imagine there’s no heaven two variables:

a="aa qq
bb ww
cc ee"

b="11 44
22 55
33 66"

And we want to see this as the result:

aa qq | 11 44
bb ww | 22 55
cc ee | 33 66

It’s not an issue having Bash and arrays:

#!/usr/bin/env bash

a="aa qq
bb ww
cc ee"

b="11 44
22 55
33 66"

IFS=$'\n' read -d '' -a a_arr <<< "$a"
IFS=$'\n' read -d '' -a b_arr <<< "$b"

for  i in ${!a_arr[@]}; do
	echo ${a_arr[i]} "|" ${a_arr[i]}
done

The main trick is done with read command which stores lines in arrays, while the rest is just a loop which scans arrays to print lines with the same index.

But life is not always easy and sometimes one could still deal with pure old Bourne shell without any hints on arrays where set command was utilised to create $@ array of $1 to $n elements. Agree, this is not always handy.

So, in the worst case it’s always possible to use a counter variable and an external tool to scan over the strings. For example, awk:

#!/bin/sh

a="aa qq
bb ww
cc ee"

b="11 44
22 55
33 66"

cnt=0
echo "$a" | while read -r ln; do
	cnt=`expr $cnt + 1`
	printf "$ln | "
	printf "$b" | awk -v c="$cnt" 'NR==c {print}'
done

or even like this:

#!/bin/bash

a="aa qq
bb ww
cc ee"

b="11 44
22 55
33 66"

for l in $(seq 1 `wc -l <<< "$a"`); do
	awk -v l="$l" 'BEGIN {ORS=" | "} NR==l {print}' <<< "$a"
	awk -v l="$l" 'NR==l {print}' <<< "$b"
done

Keeping in mind external tools and languages, there are much more possibilities to do the task, but lets stop on this for a while 🙂

Advertisements

About mezzantrop

12+ years of experience in large SAN and storage environments: mainly Hitachi, HP and Brocade. Now I am a proud SAN/storage IBMer. Redbooks author. The BeaST – storage-system concept inventor. Empty – expect-like tool developer. FreeBSD enthusiast.
This entry was posted in Tips & tricks and tagged , , , , . Bookmark the permalink.

10 Responses to Printing lines side by side in shell

  1. Christian Andersson says:

    Isn’t your last example above still bash, due to the here-string <<< operator?

    Liked by 1 person

    • mezzantrop says:

      Yes, you are right it’s Bash operator. It looks like, I’m too carried away by making examples 🙂

      Liked by 1 person

      • Christian Andersson says:

        Alright, I don’t mind really, but as of 20-or-so years, when I was working in a highly heterogeneous Unix environment, I have “hated” RedHat and all its siblings and cousins for introducing Bash as /bin/sh in the system, which I think is a bug, still not solved by the way. Since then I have specialized as an even more notorious Vanilla-Bourne Shell user, and I am not particularly fond of Bash as a scripting language at all, certainly not when interpreted by /bin/sh, which is non-portable. Bash is a high-level interactive shell first-and-foremost, not particularly aimed at scripting. Just an old hang-up of mine! I guess I should probably seek counseling for this issue! 🙂

        Liked by 1 person

      • mezzantrop says:

        It’s so difficult to find old Bourne shell nowadays. I feel like I have to buy you a beer someday 🙂

        Liked by 1 person

      • Christian Andersson says:

        So please change the magic to #!/bin/bash, and I’ll shut up! 🙂

        Liked by 1 person

      • mezzantrop says:

        Already done, just refresh the page 🙂

        Liked by 1 person

  2. Christian Andersson says:

    Well, the Debian family of Linuxes uses Dash as its system-shell, which is a minimal POSIX-compliant implementation of /bin/sh, a direct descendant of the NetBSD version of the Almquist shell (ash), according to its man-page it was ported to Linux in 1997 and renamed to dash in 2002. This is, I suppose, what you’ll find in the BSD:s in general today, as they try to avoid GNU. 20 years ago I used it in what was then Solaris 7-8, which was much more BSD than Linux.

    I like the beer suggestion. Where in the world do I find you? The US? Personally, I am still in Sweden.

    Liked by 1 person

    • mezzantrop says:

      It was my fault to test shell scripts on the Mac laptop (as I thought it has strong BSD roots). But it turns out MacOS uses bash as /bin/sh interpreter. Next time I’ll better relay on FreeBSD.

      Originally from Russia, now I’m in Czech Republic which is famous for beer. So at least we are on the same continent 🙂

      Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.