At the begining i have this scipt that put the stdout in a file.txt :
find .. -type f -not \( -path '/dev/*' -or -path '/proc/*' -or -path '/sys/devices/*' \) -print0 |
xargs -0 bash -c 'paste -d ";" <(md5sum "$@") <(sha1sum "$@") <(sha256sum "$@") <(du -lh "$@")' bash
but it returns the path 5 times with spaces which makes things hard to parse.
So I did this :
find / -type f -not \( -path '/dev/*' -or -path '/proc/*' -or -path '/sys/devices/*' \) -print0 |
xargs -0 bash -c `paste -d ";" <(md5sum "$@" | awk "{print $1}") <(sha1sum "$@" | awk "{print $1}") <(sha256sum "$@" | awk "{print $1;}") <(du -lh "$@"| awk "{print $1;}")` bash
But it's not working
How would you do ?
I just don't know how to get : md5;sha1;sha256;size;path;md5;sha1;sha256;size;path;md5;sha1;sha256;size;path;md5;sha1;sha256;size;path;md5;sha1;sha256;size;path;md5;sha1;sha256;size;path; etc ...
Basically, all on 1 line.
CodePudding user response:
In your second command, you used backtick "quotes" for xargs -0 bash -c `...` bash
. Those behave like $(...)
so the command string was executed before find | xargs
even started.
And in that command string, bash replaced $1
before awk
even started.
Command strings with nested quotes are easier to write in multiple steps using one helper variable for each level of quoting, but since you are using bash, you can export a function instead, which makes things trivial.
Your command correctly wrapped
f() {
paste -d ";" \
<(md5sum "$@" | awk '{print $1}') \
<(sha1sum "$@" | awk '{print $1}') \
<(sha256sum "$@" | awk '{print $1}') \
<(du -lh "$@" | awk '{print $1}')
}
export -f f
find / -type f -not \( -path '/dev/*' -or -path '/proc/*' -or -path '/sys/devices/*' \) -print0 |
xargs -0 bash -c 'f "$@"' bash
Slightly improved and adapted to your needs
As you wanted, we can print all fields for all files in a single line
by replacing (tr
) each \n
by an ;
. The paths are not quoted in any way. If they contain a ;
or linebreak, parsing the result could be difficult. If you need some for of quoting try printf %q
or sed 's/.../.../g'
.
f() {
paste -d ";" \
<(md5sum "$@" | awk NF=1) \
<(sha1sum "$@" | awk NF=1) \
<(sha256sum "$@" | awk NF=1) \
<(du -lh "$@" | awk NF=1) \
<(printf '%s\n' "$@") |
tr '\n' ';'
}
export -f f
find / \( -path /dev/ -o -path /proc/ -o -path /sys/devices/ \) -prune -o \
-type f -exec bash -c 'f "$@"' bash