-1

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.

akmot
  • 63
  • 8
  • 2
    The `$1` awk constructs need to be escaped so that bash does not interpret them as positional parameters. – glenn jackman Jul 18 '22 at 15:37
  • 1
    It might be hard to read, but it's not hard to parse. Just pipe the output of your original command to something like `awk -F; '{print $1, $3, $5, $7, $9}'` (adjust the actual column numbers as needed). – chepner Jul 18 '22 at 16:38
  • @chepner I don't think so. The filename can contain spaces (which are not escaped by my coreutils) and contain substrings that look like hashes themselves. – Socowi Jul 18 '22 at 18:24

1 Answers1

2

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 form of quoting try printf %q or sed [-z] '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 +
Socowi
  • 25,550
  • 3
  • 32
  • 54
  • or simply replace every instance of `cut ...` or `awk { … } ` with : `awk NF=1` – RARE Kpop Manifesto Jul 18 '22 at 20:56
  • I have no idea of what "NF" means. – akmot Jul 19 '22 at 06:28
  • @RAREKpopManifesto Great suggestion, thanks! I didn't know that you could assign `NF`, but at least I know [how to look things up](https://www.gnu.org/software/gawk/manual/gawk.html#index-NF-variable-2). – Socowi Jul 19 '22 at 07:04
  • 2
    @akmot : `NF` doesn't have an official acronym definition but most would say "number of fields" (i.e. # of columns), so `NF = x` means keep all fields/columns from 1 to x, `NF = 1` means keeping only 1st column, and `NF = 0` means wipe the entire row clean. setting NF to floating point value will have it rounded *mostly* down to nearest integer (i think if you set like 3.999999…… for a very long chain of 9s it *might* round up to 4), while setting `NF` to anything less than 0 is a fatal error – RARE Kpop Manifesto Jul 20 '22 at 01:08
  • 1
    @akmot : while `NF` is being set automatically by `awk` when each row is read in and parsed for your convenience, there's absolutely nothing sacred about `NF` - other than not setting it negative values, feel free to manipulate `NF` to your advantage, despite a widely held belief that `NF` is somehow a third rail that shouldn't be touched with a 10 ft pole – RARE Kpop Manifesto Jul 20 '22 at 01:20