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' "$@"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.