Comparing the output of 2 commands using test without temporary variables

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?

задан 23 August 2020 в 02:41

1 ответ

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
ответ дан 24 August 2020 в 08:20

Другие вопросы по тегам:

Похожие вопросы: