My environment: Linux Redhat, Bash 3.5
I have created a bash script to list all of files in sub directories using script below.
#!/bin/bash
for i in $( find . -maxdepth 1 -mindepth 1 -type d ); do
b=$(echo $i | awk '{print substr($1,3); }' )
find $i -type f > $i/$b.txt
done
I want to add sha1sum
to my script, I've edit it as shown below.
#!/bin/bash
for i in $( find . -maxdepth 1 -mindepth 1 -type d ); do
b=$(echo $i | awk '{print substr($1,3); }' )
find $i -type f ! -iname '*thumbs.db*' -printf "%b:" -exec sha1sum -b {} \; > ./$i/$b.txt
done
The second code is failed with error below
No such file or directory
Since you don't specify in what way your attempt failed [See note 1, below], I've just provided some thoughts about how to solve the underlying question of producing lists of checksums for each directory.
Your use of
find
is both unnecessary and unsafe (if there are any directories whose names include whitespace or shell metacharacters.For example,
is roughly the same as the "glob"
except that the glob does not perform pathname expansion or word-splitting on the individual directories. Furthermore, you could use the glob
*/
, which will avoid the./
prefix, which you evidently don't want.Also,
could be written much more simply as
or
But, as noted above, you could use a glob and thereby avoid any having to remove the prefix.
So you could have simply written:
Note the quotes around the variable expansions. If you really need the
%b
format to print filenames, then you definitely need to quote the expansions to avoid problems with whitespace and shell metacharacters, but anyway you should develop the a habit of quoting variable expansions.That will produce a slightly different output than your script since it doesn't place the
./
at the beginning of each line in the output file, but if you really wanted that you could usefind "./$b" ...
.I don't understand why you feel the need to use
printf
to output the filename for the SHA-1 checksums, becausesha1sum
already prints the filename. It's true that it does so after the checksum instead of before. There is actually a good reason for that behaviour: since there is no way of knowing what characters the filename might include, putting the checksum first makes it easier to parse the output.Note that in the output of
sha1sum
, the output for each file whose name includes a backslash or newline, the checksum line will start with a backslash and the backslash and newline characters in the filename will be escaped. This produces an effect somewhat similar to that of using the%b
format to printf.If you really want to turn the order around, you can do so easily enough with awk:
Using
+
instead of;
to terminate the-exec
option letsfind
execute the command with a list of filenames instead of just a single filename, which is much more efficient.Notes
See the Stack Overflow help page, from which I quote:
"It doesn't work" is not a "specific problem or error". You should always include the literal text of the error message or a clear statement of how the result of the program failed to meet your expectations.