2

Hello I have a file containing these lines:

apple
12
orange
4
rice
16

how to use bash to sort it by numbers ? Suppose each number is the price for the above object.

I want they are formatted like this:

12 apple
4 orange
16 rice

or

apple 12
orange 4
rice 16  

Thanks

nu11p01n73R
  • 26,397
  • 3
  • 39
  • 52
Cong Wang
  • 93
  • 1
  • 8

6 Answers6

5

A solution using paste + sort to get each product sorted by its price:

$ paste - -  < file|sort -k 2nr
rice    16
apple   12
orange  4

Explanation

From paste man:

Write lines consisting of the sequentially corresponding lines from each FILE, separated by TABs, to standard output. With no FILE, or when FILE is -, read standard input.

paste gets the stream coming from the stdin (your <file) and figures that each line belongs to the fictional archive represented by - , so we get two columns using - -

sort use the flag -k 2nr to get paste output sorted by second column in reverse numerical order.

Juan Diego Godoy Robles
  • 14,447
  • 2
  • 38
  • 52
1

you can use awk:

awk '!(NR%2){printf "%s %s\n" ,$0 ,p}{p=$0}' inputfile

(slightly adapted from this answer)

If you want to sort the output afterwards, you can use sort (quite logically):

awk '!(NR%2){printf "%s %s\n" ,$0 ,p}{p=$0}' inputfile | sort -n

this would give:

4 orange
12 apple
16 rice
Community
  • 1
  • 1
Chris Maes
  • 35,025
  • 12
  • 111
  • 136
  • dinging this solution for ( 1 ) having to use `modulo %` operator, ( 2 ) splitting unnecessary fields, and ( 3 ) `p` updates every row when it should've been every other row – RARE Kpop Manifesto Sep 23 '22 at 15:08
0

Another solution using awk

$ awk '/[0-9]+/{print prev, $0; next} {prev=$0}' input
apple 12
orange 4
rice 16
nu11p01n73R
  • 26,397
  • 3
  • 39
  • 52
0
while read -r line1 && read -r line2;do
    printf '%s %s\n' "$line1" "$line2"
done < input_file

If you want lines to be sorted by price, pipe the result to sort -k2:

while read -r line1 && read -r line2;do
    printf '%s %s\n' "$line1" "$line2"
done < input_file | sort -k2
Rany Albeg Wein
  • 3,304
  • 3
  • 16
  • 26
0

You can do this using paste and awk

$ paste - - <lines.txt | awk '{printf("%s %s\n",$2,$1)}'
12 apple
4 orange
16 rice
Logan Lee
  • 807
  • 9
  • 21
  • If you are using Awk anyway, you can get rid of the `paste` trivially; but then this simply repeats solutions from earlier answers. – tripleee Sep 22 '22 at 08:05
0

an awk-based solution without needing external paste / sort, using regex, calculating modulo % of anything, or awk/bash loops

{m,g}awk '(_*=--_) ? (__ = $!_)<__ : ($++NF = __)_' FS='\n'
12 apple
4 orange
16 rice
RARE Kpop Manifesto
  • 2,453
  • 3
  • 11