0

I have the following CSV file as shown below with 4 columns, and I am taking input of filename from bash terminal.

Sile,Barhams,Female,[email protected]
Shae,Scotti,Male,[email protected]
Shae,Bonham,Female,[email protected]
Shay,Ert,Female,[email protected]
Simeon,Dearle,Male,[email protected]

Desired output is:

Shae,Male
Shae,Female
Shay,Female
Sile,Female
Simeon,Male

Now I tried following code snippets and got the result as shown :

cat $file | cut -d, -f1,3 | sort -k 1,1 -s

Shae,Female
Shae,Male
Shay,Female
Sile,Female
Simeon,Male

cat $file  | cut -d, -f1,3 | sort -k 1,1 -s -n

Sile,Female
Shae,Male
Shae,Female
Shay,Female
Simeon,Male

Can somebody explain my both snippets and how I can get desired one please, according to me for first code I am sorting according to first column and in case of tie I have specified stable sort to get the desired output but IDK what is the issue and in second code I wonder how "Sile" appears on the top.

4
  • If supported by your sort implementation, the --debug option will likely be of help.
    – fra-san
    Apr 9, 2021 at 11:43
  • Please tell me what changes i need to do for getting desired output... I need help as ai tried all sort of possible combinations of flags of sort
    – kuspia
    Apr 9, 2021 at 12:15
  • thnx @fra-san infact -t, worked but I would request you that how it worked ? and moreover explain my pipeline of both code that I stated above as a new answer please it will improve my understanding.
    – kuspia
    Apr 9, 2021 at 13:04
  • ah, indeed, I missed the thing with the two Shae's switching order the first time. Sorry.
    – ilkkachu
    Apr 9, 2021 at 13:40

2 Answers 2

2
cat $file | cut -d, -f1,3 | sort -k 1,1 -s

Shae,Female
Shae,Male
Shay,Female
Sile,Female
Simeon,Male

You get that because the fields -k refers to are the blank separated fields by default and Shae,Female sorts before Shae,Male.

You need the -t option to tell it to use the comma as a separator instead:

-t, --field-separator=SEP
use SEP instead of non-blank to blank transition

$ cat "$file"  | cut -d, -f1,3 | sort -t, -k 1,1 -s
Shae,Male
Shae,Female
Shay,Female
Sile,Female
Simeon,Male

cat $file  | cut -d, -f1,3 | sort -k 1,1 -s -n

Sile,Female
Shae,Male
Shae,Female
Shay,Female
Simeon,Male

Here, with -n, the sorting is based on the numerical value of the data. But you don't have a numeric strings here: all non-numeric strings will be treated as zeroes. Hence, effectively no primary sorting rule. With -s, the order will be left as-is. Without -s, sort will fall back to a textual sort to get some result.

1

Strange. When I apply your pipeline to that data, I get

Sile
Shae
Shae
Shay
Simeon

Let's have a closer look at the pipeline:

cat filename | grep "^.\{0\}S" | cut -d, -f1,6 | sort -s -n -k1,1

First, simplify it to

grep "^S" filename | cut -d, -f1,6 | sort -s -n -k1,1

You don't need the cat (it's sometimes called "cat abuse"), and the regular expression asks for zero characters after the beginning of a line, followed by S. This is equivalent to a line that starts with S.

Why do you cut out fields 1 and 6 when there are only two fields? And I don't believe that the result keeps the second field. Something is not right here, but let's ignore the strange cut.

You perform a numerical sort. Since there is no number in the file and -s is specified, the order remains as it is. Remove the -n and/or the -s.

3
  • In particular, it's the combination of numeric and stable that gives the result that nothing happens. Without -s, it would sort the lines with equal numerical value (i.e. all) based on the text order (well, my sort does).
    – ilkkachu
    Apr 9, 2021 at 10:26
  • I modified question please now do the needful and I would request to remove previous comments so to have have more clear answer.
    – kuspia
    Apr 9, 2021 at 11:11
  • The first snippet has the desired result. My answer explains why. I can't explain the cat, though. Apr 9, 2021 at 13:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .