Home > Mobile >  Bash; check if a folder exist while the folders are numbered
Bash; check if a folder exist while the folders are numbered

Time:03-26

I have a series of folders (A1, A2, ...) and some subfolders, but I only need to check the subfolders which follow this pattern 0$n_st* and I do not need to check the rest of the subfolders:

A1/
        01_stjhs_lkk/
        02_stlkd_ooe/
        03_stoie_akwe/
        ...
A2/
        01_stpw_awq/
        02_stoe_iwoq/
        03_stak_weri/
        ...
...

I want to find the subfolder which has largest number (0$n) (the number of subfolders varies among different folders), then go to the subfolder and grep something and repeat the process over other folders (A1, A2, ...) here is my script which does not work (seems the if condition has some problem)

for dd in */; do 
   cd "$dd" # A1, A2,...
       for num in {8,7,6,5,4,3,2,1}; do
               if [  -d 0${num}_st* ]; then
                  echo "0${num}_st*"
                  cd "0${num}_st*"
                  echo $(grep -i 'xyz       f' 04_*.log) #grep this line from log file
                  break
               fi
               cd ..
       done
       cd ..
done

CodePudding user response:

The immediate problem is that if [ -d ... ] will produce a syntax error if ... is a wildcard which matches more than one file. You can work around this in various ways, but probably the simplest which matches your (vague) requirements is something like

for dd in */; do
    for dir in "$dd"/0[0-9]_st*/; do
        : nothing
    done
    # the variable `$dir` will now contain the alphabetically last match
    grep -i 'xyz       f' "$dir"/04_*.log
done

If the directories contain different numbers of digits in their names, sorting them alphabetically will not work (2 will come after 19) but your examples only show names with two digits in all cases so let's assume that's representative.

Demo: https://ideone.com/1N2Iui

Here's a variation which exhibits a different way to find the biggest number by using sort -n and which thus should work for directories with variable numbers of digits, too.

for dd in */; do
    biggest=$(printf '%s\n' "$dd"/0*_st*/ | sort -d / -k2,2n | tail -n 1)
    grep -i 'xyz       f' "$biggest"/04_*.log
done

Because the wildcards already end with /, the / after e.g. "$dd"/ is strictly speaking redundant, but harmless. You can take it out (at the cost of some legibility) if it disturbs you (or you are on a weird system where double slashes have a special meaning to the file system).

CodePudding user response:

Suggesting find command.

find . -type d -printf "%f\n" |grep "^0"|sort -n|tail -n1

Notice this find command scans recursively all directories under current directory.

In order to limit find command to specific directories dir1 dir2 you need to specify them before -type option.

find dir1 dir2 -type d -printf "%f\n" |grep "^0"|sort -n|tail -n1

Explanation

  • find . -type d
    Prints all all the directories and subdirectories under current directory

  • find . -type d -printf "%f\n"
    Prints only the directory name, not the directory path.

  • grep "^0"
    Filter only directory names starting with 0

    If matching more than required directories, possibly refine grep filter: grep "^0[[:digit:]]\ _" as well.

  • sort -n
    Sort directory names numerically

  • tail -n1
    Print the last directory

  • Related