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?
1 Answer
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 17As 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 10