Using echo $line
automatically includes a newline - which you can suppress with the -n
option (sometimes - see below). So this doesn't work:
echo $line | md5sum | awk '{print $1}' >> md5File.txt
But on bash this does:
echo -n $line | md5sum | awk '{print $1}' >> md5File.txt
But Not all versions of echo
have an -n
option. The echo documentation says:
If the first operand is -n, or if any of the operands contain a backslash ( '\' ) character, the results are implementation-defined.
... On XSI-conformant systems, if the first operand is -n, it shall be treated as a string, not an option.
Another alternative is using bash's printf
command. The printf documentation says:
The printf utility was added to provide functionality that has historically been provided by echo. However, due to irreconcilable differences in the various versions of echo extant, ...
So printf
is the reliably portable way to go. Here is a related answer with more details: https://unix.stackexchange.com/questions/65803/why-is-printf-better-than-echo
But using printf
is dangerous if you don't specify a format string, so even though this seems to work:
printf $line | md5sum | awk '{print $1}' >> md5File.txt
It will fail spectacularly when $line
contains a percent sign or a backslash. The first argument to printf
is the format string and is treated specially. If the format string is invalid then printf
produces an error to stderr and an empty string to stdout, which gives the wrong answer. So instead you need:
printf "%s" "$line" | md5sum | awk '{print $1}' >> md5File.txt
The %s
tells printf
to expect one more string parameter (which just happens to be $line
) and you get the right output.
Fun fact: if you did want printf
to add a trailing newline (you don't in this case) then you would
printf "%s\n" "$line" | md5sum | awk '{print $1}' >> md5File.txt