linuxbashexecstatmd5sum

How to combine `stat` and `md5sum` output line by line?


stat part:

$ find * -depth -exec stat --format '%n %U %G' {} + | sort -d > acl_file
$ cat acl_file
xfce4/desktop/icons screen0-3824x1033.rc john john
Code/CachedData/f30a9b73e8ffc278e71575118b6bf568f04587c8/index-ec362010a4d520491a88088c200c853d.code john john
VirtualBox/selectorwindow.log.6 john john

$ find * -depth -exec md5sum {} + | sort -d > md5_file $ cat md5_file

3da180c2d9d1104a17db0749d527aa4b  xfce4/desktop/icons screen0-3824x1033.rc
3de44d64a6ce81c63f9072c0517ed3b9  Code/CachedData/f30a9b73e8ffc278e71575118b6bf568f04587c8/index-ec362010a4d520491a88088c200c853d.code
3f85bb5b59bcd13b4fc63d5947e51294  VirtualBox/selectorwindow.log.6

How to combine stat --format '%n %U %G' and md5sum and output to file line by line,such as:

3da180c2d9d1104a17db0749d527aa4b  xfce4/desktop/icons screen0-3824x1033.rc john john
3de44d64a6ce81c63f9072c0517ed3b9  Code/CachedData/f30a9b73e8ffc278e71575118b6bf568f04587c8/index-ec362010a4d520491a88088c200c853d.code john john
3f85bb5b59bcd13b4fc63d5947e51294  VirtualBox/selectorwindow.log.6 john john

Solution

  • This is really just a minor variation on @Zilog80's solution. My time testing had it a few seconds faster by skipping reads on a smallish dataset of a few hundred files running on a windows laptop under git bash. YMMV.

    mapfile -t lst< <( find . -type f -exec md5sum "{}" \; -exec stat --format '%U %G' "{}"  \; )
    for ((i=0; i < ${#lst[@]}; i++)); do if (( i%2 )); then echo "${lst[i]}"; else printf "%s " "${lst[i]}"; fi done | sort -d
    

    edit

    My original solution was pretty broken. It was skipping files in hidden subdirectories, and the printf botched filenames with spaces. If you don't have hidden directories to deal with, or if you want to skip those (e.g., you're working in a git repo and would rather skip the .git tree...), here's a rework.


    shopt -s dotglob    # check hidden files 
    shopt -s globstar   # process at arbitrary depth
    for f in **/*; do   # this properly handles odd names
      [[ -f "$f" ]] && echo "$(md5sum "$f") $(stat --format "%U %G" "$f")"
    done | sort -d