Using head Command in Linux: Display the first five lines of multiple files, sorted alphabetically by file name

Hey everyone!
This is my first time posting on this forum.

I am kind of new to Linux and bash, but I have been learning. I recently read the article Using head Command in Linux, and I completed all of the exercises except one.

For Intermediate Users #1: " Display the first five lines of multiple files, sorted alphabetically by file name (Hint: pipe to sort command)"

Obviously, my first attempt was like this:

head -n 5 haruki.txt agatha.txt | sort

But that sorts all of the lines along with the file names, so everything gets jumbled. Like below:

==> agatha.txt <==
A Wild Sheep Chase (1982)
Hard-Boiled Wonderland and the End of the World (1985)
==> haruki.txt <==
Hear the Wind Sing (1979)
Norwegian Wood (1987)
Pinball, 1973 (1980)
The Man in the Brown Suit
The Murder on the Links
The Mysterious Affair at Styles
The Secret Adversary
The Secret of Chimneys

My reading of the prompt for this task is that top 5 lines of agatha.txt would be sorted, then the top 5 lines of haruki.txt would be sorted, so the above isn’t right. I have tried reading the man page for sort, but there wasn’t anything there that would allow me to ignore the title line, and then only sort the the titles per file. Well, other than sorting the files outside of the head command and then running the head command (which would work).

Is there a more elegant way to do this, or am I just misreading the prompt and the above is what was wanted?

Thanks!

I reckon I’d output to a temporary file first (or a variable “buffer”), then sort that…

Maybe something like

THING=$(head -5 haruki.txt agatha.txt)

Then

echo $THING | sort -n

There’s probably a better way, but would probably involve breaking out awk and some obtuse regex…

You could do both above on a single line too :

THING=$(head -5 haruki.txt agatha.txt) ; echo $THING | sort -n

Or :
THING=$(head -5 haruki.txt agatha.txt) && echo $THING | sort -n

But don’t take my word for it - Hmmm - not sure how echo will treat a multiple line string… interesting… I should test my supposition… YMMV

Also - I note the Japanese author there “Haruki (Murakami)” - one of my favourites… I haven’t read Norwegian Wood (it’s a great Japanese movie BTW), but I’ve read most of his other stuff like 1Q84, Kafka On The Shore, The Wind Up Bird Chronicle and more…


I get a blank line in some of the output - need to weed that out somehow :
THING=$(head -5 list1 list2) ; echo $THING |grep -v \=\= |sort -n
(note have to grep ignore the “==” in output too)


Uses a 2nd grep to weed out blank lines :

╭─x@titan ~/ResilioSync/scripto  
╰─➤  THING=$(head -5 list1 list2) ; echo $THING |grep -v \=\= |grep -v '^[[:space:]]*$'|sort 
abcang/azpainter
age
ansible
azpainter
bandcamp-dl
tor
unixbench
w3m
wget
wordgrinder

I was unable to use the single grep command…
e.g. |grep '\=\=|^[[:space:]]*$'

1 Like

Sorry for the confusion.
Let’s start from the beginning.

I have two text files: Haruki.txt and Premchand.txt

Here, I would explain by taking two scenarios in mind:

  1. You want to merge the text data of both files and then sort the output
  2. You want to have sorted output of both files but without mixing the text

So let’s start with the first scenario.

  1. If you have two text files that have similar data and now you want to merge them in alphabetical order. all you have to do is use the -n flag with the desired amount of lines and append the filenames and in the end, you have to pipe your input to the sort command.

For example, if I want to merge two text files Haruki.txt and Premchand.txt for the first 5 lines in alphabetical order, I will be using the following:

head -q -n 5 Premchand.txt Haruki.txt | sort
Here’s the output:

sagar@itsFOSS:~$ head -q -n 5 Premchand.txt Haruki.txt | sort
A Wild Sheep Chase (1982)
Godan
Hard-Boiled Wonderland and the End of the World (1985)
Hear the Wind Sing (1979)
Karmabhoomi
Nirmala
Norwegian Wood (1987)
Pinball, 1973 (1980)
Rangbhoomi
Sevasadan

Remember, this will mix the text files and then sort them so the output order will only be alphabetical and not specific to a file.

Now, let’s have a look at the second scenario.

  1. If you want to use multiple files and sort the first 5 lines of each file but without mixing the output such as the first 5 lines should only be from the first text file so here’s how you do it.

Here, I will be using the same text files to make things easy:
head -q -n 5 Premchand.txt | sort && head -n 5 -q Haruki.txt | sort
Here, you’d see, I have used the && operator which will execute the first part of the command first and then will proceed to the second one.

And here’s the expected output:

sagar@itsFOSS:~$ head -q -n 5 Premchand.txt | sort && head -n 5 -q Haruki.txt | sort
Godan
Karmabhoomi
Nirmala
Rangbhoomi
Sevasadan
A Wild Sheep Chase (1982)
Hard-Boiled Wonderland and the End of the World (1985)
Hear the Wind Sing (1979)
Norwegian Wood (1987)
Pinball, 1973 (1980)

Pretty simple. Isn’t it?

3 Likes

And thanks for bringing it to our attention @Akatama

What seemed like a straight forward exercise, was indeed confusing.

We’ll try to make the instructions for such exercises more clear, perhaps add expected output to avoid ambiguity.

1 Like

OK - I didn’t realise this was a response to an It’s FOSS tutorial (maybe helpful in future to include a link to the tutorial so we’re all on the same page) :

So @sudoersagar - it’s your article, are you a fan of Haruki Murakami’s writing then, or did you just pick an author at random ?

Thank you Sagar! I knew there must be a simple, elegant solution. I think where I went wrong was I read the prompt as if it wanted the name of the file in the output as well. Re-reading the prompt I realize it never actually said that. Thank you for your detailed explanation!

@abhishek Its not problem! I misread the prompt anyway, but I do think such a change would improve future articles.

@daniel.m.tripp Thank you for trying to help me, Dan! And you are right, I should’ve included the article. I didn’t actually realize how large this forum was so, but now that I know I will include the article in the future.

As for me, I haven’t read any of Murakami’s works, although I probably will eventually. I have actually seen the Norwegian Wood film you mentioned though - saw it like 10 years ago when I was working on my bachelors degree. The Japanese Language Club put on a showing of it. It was a very good film.

2 Likes

I love Haruki and eagerly waiting for his current work (The City and Its Uncertain Walls) to be translated into English. If you ask me, Kafka on the Shore is the best and 1Q84 is overrated.

1 Like

I’m glad you found it useful… Let me know if you face any difficulties with other questions!

I wouldnt call 1Q84 overrated, but I agree Kafka on the Shore is better, but I prefer Windup Bird Chronicle and Killing Commendatore to Kafka and 1Q84…

Don’t worry about the ommission of the original link - but took me a few posts to realise what the OP was referring to.

It’s a good movie - but - even better is the Lennon / McCartney song that inspired the novella (was mostly Lennon) - I was on huge Beatles kick last year (in fact a 12 month “binge” from 2021 after seeing those Peter Jackon edited documentaries in 2021) - I now have all their (Beatles) best stuff (1966-1970) on vinyl now… I can’t believe how short all the songs on Rubber Soul are, they’re nearly all immortal…

Due to some reason, I left Wind-Up Bird Chronicle and now I’m required to start again as I forgot the plot.
Pretty huge book but unlike 1Q84, the magical makes more sense to me (IDK why)

1 Like