-1

I am passing arguments to bash function, composed of directories and files. The following code validates the arguments before staring then in the array fdir.

declare -A tag
for arg in "$@"; do
  printf '%s\n' "arg: $arg"  
  [[ -d "$arg" || -f "$arg" ]] || continue
  [[ ${tag[$arg]} ]] && continue
  fdir+=("$arg")
  tag[$arg]=1
done

Finally, I pass the contents of fdir to the find command and finally run head on the matched files.

local _GREP="/bin/grep --color"
hn=13
sufx=( \( -name '*.sh' -o -name '*.c' \) )
mxdpt=( -maxdepth 3 )
find "${fdir[@]}" -type f "${sufx[@]}" "${mxdpt[@]}"  \
  -exec head -v -n "$hn" '{}' + 

Because I use sufx in the file command, if I pass a different type of file (e.g. /home/flora/file.org), the find will not find a match.

One solution would be to have directories to precede files in the array fdir. Loop through each element in fdir and set sufx=() as soon as I detect the first file.

   declare -A tag

   local daggr=()
   for arg in "$@"; do
     [[ ! -d "$arg" ]] || continue
     [[ ${tag[$arg]} ]] && continue
     daggr+=("$arg")
     tag[$arg]=1
   done

   local faggr=()
   for arg in "$@"; do
     [[ ! -f "$arg" ]] && continue
     [[ ${tag[$arg]} ]] && continue
     faggr+=("$arg")
     tag[$arg]=1
   done

   fdir=( "${daggr[@]}" "${faggr[@]}" )

 for (( i=0 ; i < $n ; i++ )); do
   [[ -f "${fdir[$i]}" ]] && { sufx=() ; mxdpt=() ; }
   find "${fdir[$i]}" -type f "${sufx[@]}" "${mxdpt[@]}"  \
     -exec head -v -n "$hn" '{}' +
 done

Any advice on better or simpler ways that I could try?

6
  • "arbitrary files, but allow matches using sufx for directories" makes in my understanding sense only if you have directories with names *.sh and *.c. Please give an example tree structure. find shall descend only into (sub)directories with these suffixes? Nov 19, 2021 at 1:41
  • *.sh and *.c are the file extensions. I want to be able to do myfunc /home/flora/lin /home/flora/mol/edv.f.
    – Vera
    Nov 19, 2021 at 1:47
  • One solution would be to have directories to precede files in the array fdir. Loop through each element in fdir and set sufx=() as soon as I detect the first file.
    – Vera
    Nov 19, 2021 at 1:50
  • I suspect you need to run two different find commands, one for directories and one for files. BTW, what versions of bash allow sufx=( ( -name *.sh -o -name *.c ) ) without quotes/escapes? Nov 19, 2021 at 2:09
  • 1
    Sounds like you want either use the -H option of find or change the [[ -f/-d file ]] to [[ -f/-d file && ! -L file ]] Nov 19, 2021 at 7:29

1 Answer 1

1

First, you have to quote this:

sufx=( \( -name '*.sh' -o -name '*.c' \) )

If find shall apply -exec to all files in "${fdir[@]}" but only to certain files within the passed directories then a simple approach would be to have two find calls:

find "${fdir[@]}" -maxdepth 0 -type f -exec head -v -n "$hn" '{}' +
find "${fdir[@]}" -mindepth 1 -type f "${sufx[@]}" "${mxdpt[@]}"  \
  -exec head -v -n "$hn" '{}' +
5
  • I want to avoid a repeat.
    – Vera
    Nov 19, 2021 at 2:00
  • 1
    @Aardvark, the alternative would be to add some -path filepath_escaped ored together for each of the regular files (with wildcard characters escaped) which IMO would not be worth the effort. Nov 19, 2021 at 7:30
  • Is it acceptable to pass a filename rather than a directory to the find command? E.g. find /home/flora/linear.rc -print
    – Vera
    Nov 19, 2021 at 10:56
  • @Aardvark, yes, of course, can be a file of any type whether it's regular, fifo, directory, symlink, etc. However note that unless you pass some -H/-L option (or use the -follow predicate), files of type symlinks will be considered as symlinks not as whatever type the file they eventually resolve to it. For symlinks to directories for instance, that means the corresponding directory will not be walked down. Compare with ['s -d or -f which tests the type of the file after symlink resolution (respectively for dir or regular, excluding all other types of files). Nov 19, 2021 at 14:58
  • Will the command find -H "${fdir[@]}" -type f \( -name '*.sh' -o -name '*.c' \) always work when passing files and directories in fdir?
    – Vera
    Nov 19, 2021 at 16:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .