how do you compare comandline arguments in bash example i have 5 or more arguments and 2 of the arguments are the same how can do it any suggestions? my problem is that i need to compare 2 or more arguments if any of the arguments are the same sleep for 1 sec

May be there is an easier way, but here is what I can think of..

total_params=`echo $* | sed 's/ */\n/g' | sort | sed '/^$/d' | wc -l`
unique_params=`echo $* | sed 's/ */\n/g' | sort -u | sed '/^$/d' | wc -l`
[ $total_params -ne $unique_params ] && echo "repeat" || echo "no repeat"

PS: There is a bit of catch with sort as it adds some newline chars by itself, that's why the /^$/d at end.

Edited 5 Years Ago by thekashyap: n/a

To add to what thekashyap provided, you already have the count of arguments in the $# variable and, in bash at least, you do not need to worry about multiple spaces so you can get away without both sed calls.
For instance:

[ $# -ne `echo $* | tr ' ' '\n' | sort -u | wc -l` ] && echo "Duplicates"

Which is pretty terse, you may want to break it up a bit like

UNIQ=`echo $* | tr ' ' '\n' | sort -u | wc -l`
if [[ $# -ne $UNIQ ]]; then
   echo "Duplicates"
fi

To add to what thekashyap provided, you already have the count of arguments in the $# variable and, in bash at least, you do not need to worry about multiple spaces so you can get away without both sed calls.
For instance:

[ $# -ne `echo $* | tr ' ' '\n' | sort -u | wc -l` ] && echo "Duplicates"

Which is pretty terse, you may want to break it up a bit like

UNIQ=`echo $* | tr ' ' '\n' | sort -u | wc -l`
if [[ $# -ne $UNIQ ]]; then
   echo "Duplicates"
fi

Did you test your code? (I haven't)
I ask because as I said in my post:
"
PS: There is a bit of catch with sort as it adds some newline chars by itself, that's why the /^$/d at end.
"

Did you test your code? (I haven't)

Yes.
Example run:

$ cat t.sh 
#!/bin/bash
[ $# -ne `echo $* | tr ' ' '\n' | sort -u | wc -l` ] && echo "Duplicates"
$ ./t.sh a
$ ./t.sh a b
$ ./t.sh a b a
Duplicates
$ ./t.sh a b a      d
Duplicates
$ ./t.sh a b c      d
$ ./t.sh a b c      d          3
$ ./t.sh a b c      d          3        "a  v"
$ ./t.sh a b c      d          3        "a  v"       "a  v"
Duplicates
$ 
$
$ echo "a b c d e" | tr ' ' '\n' | sort -u
a
b
c
d
e
$

As you can see I dont experience the problems you do with sort .


[Edit] You actually introduce the problem yourself by using sed in the first place. For instance:

$ echo "a b c d e" | sed 's/ */\n/g'

a
b
c
d
e

$

Edited 5 Years Ago by L7Sqr: n/a

what if example in the command line i wrote ./t.sh txt.txt /home/txt.txt how can i make it work when other arguments are paths

You actually introduce the problem yourself by using sed in the first place.

Thanks. Problem is with patter instead of sed . Following works like yours.

unique_params=`echo $* | sed 's/ /\n/g' | sort -u | wc -l`
[ $# -ne $unique_params ] && echo "repeat" || echo "no repeat"

PS: Now that you posted the examples, I couldn't help but notice that both our solns would fail for ./t.sh a b c d 3 "a v" .. :)
[EDIT] Just realized the simple soln is NOT to use $#..

[root@forssa tmp]# cat xxx
#!/bin/bash

uniq=`echo $* | sed 's/ /\n/g' | sort -u | wc -l`
tota=`echo $* | sed 's/ /\n/g' | sort | wc -l`
[ $uniq -ne $tota ] && echo "repeat" || echo "no repeat"

[ $# -ne `echo $* | tr ' ' '\n' | sort -u | wc -l` ] && echo "Duplicates" || echo "No duplicates"

exit 0

[root@forssa tmp]# ./xxx a b
no repeat
No duplicates
[root@forssa tmp]# ./xxx a b "c d"
no repeat
Duplicates
[root@forssa tmp]# ./xxx a b "c d" b
repeat
No duplicates
[root@forssa tmp]# ./xxx a b "c d" "c d"
repeat
No duplicates
[root@forssa tmp]#

what if example in the command line i wrote ./t.sh txt.txt /home/txt.txt how can i make it work when other arguments are paths

As is invariably teh case with YOUR homework, YOU would also have to do something. :)
1. txt.txt and /home/txt.txt: Are duplicates only if pwd=/home
2. You can use basename. If you want a dumb comparison. I.e. if two files have same name but are in different directory they still considered same.
3. For smarter comparision: You can get the inode number (using stat) of each path after following links (if any) and find duplicates in the list of inode numbers using the solns posted here.

Edited 5 Years Ago by thekashyap: n/a

This article has been dead for over six months. Start a new discussion instead.