0
#!/bin/bash
pat="'*.ab' -o -name '*.bc'"
open="\("
close="\)"
path=path

find $path -type f $open -name $pat $close

Above code doesn't show any output for find. Do help

  • What is path=path supposed to do? – scai Jun 19 '17 at 8:54
  • You don't need to escape ( inside quotes. – Michael Homer Jun 19 '17 at 8:57
  • @scai path is the location where the files are present – Arjun Jun 19 '17 at 9:01
  • Our reference question on quoting explains the problem with $pat. – Gilles Jun 20 '17 at 22:18
2
pat="'*.ab' -o -name '*.bc'"
find $path -type f $open -name $pat $close

This doesn't do what you want: the quotes within the variable pat aren't taken as quotes, but as literal characters. After $pat is expanded, it's wordsplit, resulting in the words '*.ab', -o, -name and '*.bc', with the single quotes still intact. So unless you have filenames with single quotes within them, this will not match.

path=path

This sets the variable path to the literal string path, but I suppose this was just a placeholder.

open="\("
close="\)"

These put literal backslashes in the variables, and find should probably complain as it gets an argument of \(. It's enough to quote the parenthesis once, so either open="(" or open=\(

If you need to build a list of expressions for find, use a shell with arrays (Bash or almost anything but plain sh):

args=()  
args+=( -name "*.ab" )
args+=( -or -name "*.bc" ) 

find ... \( "${args[@]}" \)

Wrap the array-building in a loop as necessary.

1

You're using the wrong type of variable, and forgetting to quote them.

Here, you need an array to store more than one argument:

#! /bin/bash -
pat=('*.ab' -o -name '*.bc')
open='('
close=')'
path=path

find "$path" -type f "$open" -name "${pat[@]}" "$close"

Note that it's a *.ab and ( argument you want to pass to find, not '*.ab' or \(. Those quotes and backslash are part of the shell syntax.

That's only if you wanted to build a shell command line, for instance to pass to eval for the shell to evaluate it that you would do:

#! /bin/bash -
pat="'*.ab' -o -name '*.bc'"
open="\("
close="\)"
path=path

eval 'find "$path" -type f '"$open -name $pat $close"

For the shell to then evaluate:

find "$path" -type f \( -name '*.ab' -o -name '*.bc \)

Which as above results in find being called with these arguments:

  • find
  • path (content of $path)
  • -type
  • f
  • (
  • *.ab
  • -o
  • -name
  • *.bc
  • )
0

Use straightforward approach (instead of playing with variables):

find $path -type f -name "*.ab" -o \( -name "*.bc" \)
  • Pattern and path both will be arguments to the script .Hence making them dynamic – Arjun Jun 19 '17 at 9:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.