I am testing a few things out in bash, and I decided to compare the number of lines in the file with the number of unique lines. I do know that I can simply make 2 temporary variables that store the corresponding values and just compare them but I was wondering about the way of doing it in 1 line.
For example, I though it this approach would work: test `wc -l filename` -eq `uniq filename|wc -l`
. I get the error -bash: test: too many arguments
. Where is my mistake and how would you do it without using temporary variables?
You cannot do a direct comparison because wc -l file
outputs [number] file
and uniq file | wc -l
outputs only [number]
. You can do as @stelldriver suggested, redirecting the file to wc
's standard input with wc -l < file
, so that only [number]
is outputed, or use awk to get only the first field (see below).
Also, backticks are bad for readability. Prefer the $(command)
construct.
You get "too many arguments" because your expressions are not quoted, so the shell splits the [number] file
output into two words instead of only one.
All in all, this is what you are after:
test "$(wc -l file|awk '{print $1}')" -eq "$(uniq file|wc -l)"
We pass wc -l file
output to awk so as to get only the first field, the [number]
.
Just for more clarity in the answer, see what happens with your original attempt by prepending an echo
to the command:
$ echo test `wc -l file` -eq `uniq file|wc -l`
test 19 file -eq 17
As can be seen, there are 4 arguments for the test
command: 19
, file
, -eq
and 17
.
If you try the one I propose, you get a proper comparison with 3 arguments for test
:
$ echo test "$(wc -l file|awk '{print $1}')" -eq "$(uniq file|wc -l)"
test 19 -eq 17