Score:0

How to remove null in find when no file does match?

ht flag

How to remove null in stdout of find when no file does match?

Vformat=(mp4 wmv pgep mov)

for File in ${Vformat[@]}
do
      find $SrcDir -iname "*.$File" | xargs ls -l --time-style=full-iso
done
hr flag
What exactly are you trying to do here? I *suspect* you're asking how to prevent `xargs` from running when its standard input is empty (GNU xargs has a `-r` option for that) - but really you should probably be using find's `-exec` to avoid xargs altogether
Esther avatar
es flag
Hello, and welcome to Ask Ubuntu! This site is different from forums you may have previously visited, you can take the [tour](https://askubuntu.com/tour) to learn more. Specifically, we don't put "[Solved]" or similar in the titles here, since the questions are not just for you, but for everyone! If you post a question that gets good answers, you can mark a specific answer as "accepted" if it helped you.
Score:1
it flag

Increase your find-fu. Reread man find, and do something like the following ** UNTESTED ** :

Vformat=(mp4 wmv pgep mov)



find "$SrcDir" -type f \
 \( -iname '*.mp4' -o \
   \( -iname '*.wmv' -o \
     \( -iname '*.pgep' -o \
       \( -iname '*.mov' \
       \) \
     \) \
   \) \
  \) \
  -print0 | \
xargs -0 --no-run-if-empty \
    ls -l --time-style=full-iso

Here's a quick rundown:

  • The backslash inverts the "specialness" of the next character "\Newline" is treated as a space, \( and \) ARE "special" to find, and are used to group expressions.
  • "$SrcDir" Always quote variables
  • -type f We only care about files.
  • '*.mp4' Use single quotes to delay expansion by the shell
  • By combining all the -iname tests with -o (find's "OR"), you only make one pass through "$SrcDir", rather than FOUR.
  • -print0 each filename is separated by ASCII NUL (a character that, along with /, is forbidden in file names). This lets you handle Filenames with spaces and other funny characters.
  • xargs -0 accept the NUL separated list of filenames.
  • --no-run-if-empty don't execute if the generated argument list contains no filenames (in case find outputs junk at the end).

Generating the find command from Vformat is left undone. Hint: Use 2 variables, one to accumulate the "\( -iname '*.foo' -o " part, and the other to accumulate the ") "s.

Score:1
hr flag

Reading between the lines of your question, I suspect what you are really asking is "how to prevent xargs from running when its standard input is empty" so that ls is never run with no argument (which would list files in the current directory).

GNU xargs has an option for that; from man xargs:

   -r, --no-run-if-empty
          If the standard input does not contain any nonblanks, do not run
          the command.  Normally, the command is run once even if there is
          no input.  This option is a GNU extension.

However GNU find also provides a mechanism to avoid piping its output to xargs in most cases - from man find:

   -exec command {} +
          This variant of the -exec action runs the specified  command  on
          the  selected  files, but the command line is built by appending
          each selected file name at the end; the total number of  invoca‐
          tions  of  the  command  will  be  much  less than the number of
          matched files.  The command line is built in much the  same  way
          that  xargs builds its command lines.

So for example you could do

Vformat=(mp4 wmv pgep mov)

for File in "${Vformat[@]}"
do
      find "$SrcDir" -iname "*.$File" -exec ls -l --time-style=full-iso {} +
done

If you want to avoid the overhead of calling find multiple times, then one way to do that would be to convert your array of extensions into an array of -iname xxx arguments connected with the -o logical OR conjunction:

Vformat=(mp4 wmv pgep mov)

args=()
for File in "${Vformat[@]}"
do
  args+=( -o -iname "*.$File" )
done

and then

find "$SrcDir" -type f \( "${args[@]:1}" \) -exec ls -l --time-style=full-iso {} +

The array slice ${args[@]:1} removes a leading -o and the literal brackets \( and \) group the OR list since -exec has AND precedence.

Finally, if you just need file names and mtimes then you might consider using the find command's -printf instead of the external ls:

find "$SrcDir" -type f \( "${args[@]:1}" \) -printf '%TF %TT %Tz\t%p\n'
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.