Linux forum

General discussion

Using Bash Sort Command


I am new to linux and have a text file that looks like this:

123 234234 one
234 456 two
694 2349 three

Each of the lines has three specific areas: the first three digits, then a a number with a maximum of six digits, then a word. I am trying to sort this column by the second area, but only display the third column. I know that I will have to use the sort command but I cannot figure out how to get it to work.

Thanks for any help, I'm new!

Discussion is locked
You are posting a reply to: Using Bash Sort Command
The posting of advertisements, profanity, or personal attacks is prohibited. Please refer to our CNET Forums policies for details. All submitted content is subject to our Terms of Use.
Track this discussion and email me when there are updates

If you're asking for technical help, please be sure to include all your system info, including operating system, model number, and any other specifics related to the problem. Also please exercise your best judgment when posting in the forums--revealing personal information such as your e-mail address, telephone number, and address is not recommended.

You are reporting the following post: Using Bash Sort Command
This post has been flagged and will be reviewed by our staff. Thank you for helping us maintain CNET's great community.
Sorry, there was a problem flagging this post. Please try again now or at a later time.
If you believe this post is offensive or violates the CNET Forums' Usage policies, you can report it below (this will not automatically remove the post). Once reported, our moderators will be notified and the post will be reviewed.
Collapse -
use sort(1) and cut(1)

In reply to: Using Bash Sort Command

Your GNU+Linux system came with GNU's versions of the unix sort(1), tr(1), and cut(1) commands. (They've got (1) on their names because they are in chapter 1 of the local manual, "user commands.") Sort(1) does what you expect. Tr(1) (translate) is best known for implementing simple substitution ciphers, but I'm going to use its -s (squeeze) option to make sure there is only one space between each of the columns in your file. Cut(1) picks columns out of a file. It can pick them by character position or by whole words.

Each of these commands is a "filter." If you don't tell them what file(s) to read, they expect to read from a pipe. They blurt their output to "the standard output stream" which might be another pipe, your terminal, or a file. That makes them easy to chain together. Arranging that chain is bash(1)'s job. Let's say your file is textfile.

tr -s ' ' < textfile | sort -n -k2 | cut -d' ' -f3 > sortedfile

ought to do it. We squeeze the extra spaces out, sort lines numerically, keying on the second word, and cut the third column out of the result. Notice the spaces in quotes. The quotes prevent bash(1) from eating them. So tr(1) is squeezing spaces, and cut(1) is using spaces to delimit fields. The spaces surrounding the I/O redirections <, >, and | are optional, but they make your scripts easier to read. In the cut(1) command, there is no space between the -d and whatever the delimiter character is. Both sort(1) and cut(1) start counting fields at one. Some other commands start counting at zero.

We could do this in a Perl or awk(1) "one liner" but that would be harder.

Collapse -

In reply to: Using Bash Sort Command

Thanks, I figured out a way to do it that will work for me.

I used this:

sort -n +1 file.txt > outfile.txt | cut -c 14-20 outfile.txt

Collapse -

In reply to: Thanks

"sort -n +1 file.txt > outfile.txt | cut -c 14-20 outfile.txt"

The sort command reads file.txt. +1 is the same as -k2. Next you did something really obscure. The shell directive "> outfile.txt" says to redirect standard output to that file. What's not obvious is they are talking about the output of the whole pipeline, no matter where you put the directive. So that is an arcane way way to say

sort -n -k2 file.txt | cut -c 14-20 outfile.txt > outfile.txt

The strange thing is you mentioned outfile.txt as an argument to cut(1) as well. Filename arguments to cut(1) are instructions to *read* those files, not write them. And if there are only filename arguments, and no minus, cut(1) does not read its standard input, so it will ignore the pipe that sort(1) is talking into. The manpage says

cut [OPTION]... [FILE]...

(that is, there might be multiple options, or none, and there might be multiple files, or none, and the options have to go first.)


"With no FILE, or when FILE is -, read standard input."

(that is, if you want cut(1) to combine the output of a pipe with data from some files, list the files on the command line and put a minus where you want the pipe's data to come in.)

So we have sort(1) talking into a pipe that nobody is listening to, and cut reading and writing the same file. Are you sure you copied that correctly? I don't see how it can work.

The other strange thing is you are passing character columns 14 through 20 (of *something*) through cut(1). But your example data showed variable width fields. Maybe the original had the columns tabulated, but that didn't survive the Cnet forum software. That was why I used -f not -c.

One of the nice things about these text utilities is they have not changed very much in thirty-five years. The Free Software Foundation added features to the GNU versions. There was a huge effort to make them handle languages that use more than one byte to represent a character. But they're generally upward compatible with the originals. They're part of the human cultural heritage now, like the alphabet. And there are thousands of shell scripts that depend on them working exactly the way they work, so they're not *going* to change.

Popular Forums

Computer Newbies 10,686 discussions
Computer Help 54,365 discussions
Laptops 21,181 discussions
Networking & Wireless 16,313 discussions
Phones 17,137 discussions
Security 31,287 discussions
TVs & Home Theaters 22,101 discussions
Windows 7 8,164 discussions
Windows 10 2,657 discussions


This one tip will help you sleep better tonight

A few seconds are all you need to get a better night's rest.