0

I want to sort the input of the user with sort in a case (and function). But I never used this before. Do I have to use an array or something?

For example the user does:

bash test.sh 50 20 35 50

Normally in my script this would happen:

ping c -1 "192.168.0.$i"

That results in

192.168.0.50
192.168.0.20
192.168.0.35
192.168.0.50

Now I want that the last numbers are sorted and also pinged from smallest to the biggest number like this: 20 35 50 and also that if you have 2 times the same number, the script only pings that number one time.

SortNumbers(){


}


...

case

-sort ) SortNumbers;;

esac

2 Answers 2

1

You can use this:

#!/bin/bash
array=($(printf '%s\n' "$@"|sort -nu))
echo ${array[@]}

If you run test.sh 34 1 45 1 5 6 6 6, it will give output:

1 5 6 34 45

Now you can use the variable $array with a for loop like:

for i in ${array[@]};do
#do something with $i
done

Explanation:

The arguments of the script is piped to the command sort and the output is assigned into an array named array. The options -n is for numerical sort and -u is for unique.

Assumed complete code for you (for clarification):

#!/bin/bash
array=($(printf '%s\n' "$@"|sort -nu))
for i in ${array[@]};do
ping -c -1 "192.168.0.$i"
done

Using a function:

sortNumbers(){
array=($(printf '%s\n' "$@"|sort -nu))
}
sortNumbers 43 1 2 8 2 4 98 45
echo ${array[@]} ##this is just a sample use, you can put for loop here

So you can declare an array array=($@) at the begining of your script. then call the sortNumbers function with the arguments (remember to exclude -sort from the argument) when needed to sort them (it will change the variable $array with sorted content). Put the for loop outside the function so it takes whatever in the variable $array (sorted or unsorted), that way you will have it your way (choice to do sort or not).

Sign up to request clarification or add additional context in comments.

6 Comments

So to ping my ip-addresses I only have to input ping c -1 "192.168.0.$i" in the for loop? Like this: array=($(printf '%s\n' "$@"|sort -u)) SortNumbers(){ echo ${array[@]} for i in $({array[@]};do ping 192.168.0.$i done } case -sort ) SortNumbers;; esac
No, you don't need to use the sortNumber function, and the echo.
@gladius I have added a complete code sample for your particular case, You don't need to use any function to do the sorting, it's just an extra line above your for loop.
okay, Tnx. But I use it in a case. So i will put the for.... - .. done in a function and the array in the begin of my script. So i can do this: bash test.sh -sort 50 40 80 20 for example
@gladius it won't work like that... I am updating my answer with a function solution...
|
0

Try this:

#!/bin/bash

# 1. copy the scripts arguments into an array
array=($@)
# 2. Set internal field separator to newline
IFS=$'\n'
# 3. pass the array contents to sort's stdin using here-string
sorted=($(sort <<<"${array[*]}"))
# 4. pass the output of sort to uniq utility using the same technique
uniq=($(uniq <<<"${sorted[*]}"))
# 5. print the final array
printf "%s\n" "${uniq[@]}"

lcd047's shorter version:

IFS=$'\n' sorted=($(sort -nu <<<"$*"))
set "${sorted[@]}"
printf "%s\n" "$@"

Run result:

$> bash test.sh 3 2 1 45 45 3 4 4 4 1 1 1 1
1
2
3
4
45

3 Comments

Can you explain it a little bit please? I am new in shell scripting.
Or just IFS=$'\n' sorted=($(sort -nu <<<"$*")); set "${sorted[@]}"
The point of set "${sorted[@]}" is to have the changes back in $@. Try printf '%s\n' "$@"

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.