Search code examples
findexecmd5sum

Linux find exec md5sum, only the sum like this (fullpath TAB size TAB mtime TAB ctime TAB md5)


I want to view for the files in /var/www the following data: fullpath size mtime ctime md5

I ran the following command:

find /var/www/ -maxdepth 1 ! -type d -printf '%p\t%s\t%t\t%c\t' -exec md5sum {}  \;

which gives me: (fullpath size mtime ctime md5 fullpath)

/var/www/intranet/admin/tpl/view.tpl.php        1448    Wed Dec 16 18:51:06.0000000000 2015     Fri Sep 15 09:08:36.0805775786 2017     e0b7dacaf7c90fb0fbe7a69c331e36aa  /var/www/intranet/admin/tpl/view.tpl.php

How can I filter the last fullpath?????? I do not want to show it. All fields are TAB separated.

I tried:

find /var/www/  -maxdepth 1 ! -type d -printf '%p\t%s\t%t\t%c\t'
   -exec md5sum {} | awk '{print $1}'\;

for which I received the error: "find: missing argument to `-exec'"

find /var/www/ -maxdepth 1 ! -type d -printf '%p\t%s\t%t\t%c\t' -exec md5sum {} + | awk '{print $1}' 

for which I got only the md5sum.

Thanks in advance!


Solution

  • Pipelines (|) are a shell-feature. To get shell features, one needs to invoke a shell:

    find /var/www -maxdepth 1 ! -type d -printf '%p\t%s\t%t\t%c\t' -exec sh -c 'md5sum "$1" | awk '\''{print $1}'\' MD5 {} \;
    

    Or, if you prefer commands spread over multiple lines:

    find /var/www \
        -maxdepth 1 \
        ! -type d \
        -printf '%p\t%s\t%t\t%c\t' \
        -exec sh -c 'md5sum "$1" | awk '\''{print $1}'\' MD5 {} \;
    

    Notes

    1. sh -c somestring invokes a shell and instructs it to execute whatever commands are in somestring.

    2. sh -c somestring MD5 {} invokes the shell and executes somestring and assigns $0 to MD5 and $1 to whatever find substitutes for {}.

      $0 is only used by the shell when it creates error messages and otherwise unimportant.

    3. A complication is that our command, somestring, must contain both single quotes and double-quotes which is why we need escaped single-quotes.

      In our case, we want somestring to be:

      md5sum "$1" | awk '{print $1}'
      

      To prevent the main shell from substituting in for $1, we need to put this inside single-quotes. However, we can't put single-quotes inside single-quotes. The workaround is to use this for our single-quoted string:

      'md5sum "$1" | awk '\''{print $1}'\'