bashfind

bash / find : looking for the flles located in the above directories


The following script tries to search the files matching the pattern and copy them to the current directory.

# pattern to search
lig="lig*"
output=$(pwd)
# find in anywhere and copy to the current dir
find -maxdepth 1 ../../ -name "${lig}*.png" -exec cp "{}" ${output}  \;

In my situation I need to look for the $lig somewhere above the current dir, which is

/home/user/Bureau/Analyse/BCL_MDtest_haddock2/Analysis

and the lig* files are located in

/home/user/Bureau/Analyse/BCL_MDtest_haddock2/!plots

How could I define the search space for find above the current folder (reverse to the max-dep) since I am not considering all enclosed sub-folders from the current directory?


Solution

  • How could I define the search space for find above the current folder (reverse to the max-dep)

    find can only search a directory tree that is rooted at a given starting point. It cannot go upwards from there. Your attempt to then provide a sufficiently high root (such as ../../), and traverse from there down to the current directory (using a corresponding -maxdepth 2) would necessitate the active exclusion of all the undesired sibling paths that happen to share that root as a common ancestor, which is unnecessarily inefficient and not worth the effort, imo.

    Instead, if you just want to copy over some files from some upper directories, why not do it directly with one crafted cp command? Errors related to directories not containing files with that pattern could be avoided, if needed, by setting shell options: shopt -s nullglob (unset again with -u).

    cp {..,../..}/lig*.png ./
    #   ..                      first directory as one source directory
    #      ../..                second directory as another source directory
    #             lig*.png      filename pattern in the source directories
    #                      ./   current directory as the target directory
    

    If this is too limiting for your use-case (the static number of parent directories, having to list all intermediate directories, command length restrictions, etc.) and/or you want more control over how each file is processed, you could also script it by dynamically first looping over the successive parent directories, then over their individual files matching, and processing them one by one:

    pattern="lig*.png"
    updirs=2
    
    intodir="$PWD"
    while [[ $((--updirs)) -ge 0 ]]; do
      cd ..
      for file in $pattern; do
        [[ -e "./$file" ]] && cp "./$file" "$intodir"
      done
    done
    # cd "$intodir" # if you need to come back within the script