How to print last directory inside every parent directory

3393 views linux
1

I have set of directories and sub-directories as below.

aaa/180809_1047
aaa/180915_0055
aaa/181012_1545
aaa/xyz
bbb/180809_1047
bbb/180915_0055
bbb/181012_1545
bbb/181105_0000
bbb/xyz
.
.
.
zzz/180821_1555
zzz/181004_2355
zzz/xyz

Most of the sub-directories are in YYMMDD_HHMM format. Here I'm trying to print the sub-directories which are in the format YYMMDD_HHMM only (latest) from every parent directory. Below is my requirement.

output:

aaa/181012_1545
bbb/181105_0000
zzz/181004_2355

I have used find command as below:

find ./*/ -type d -maxdepth 1 -mindepth 1 -name "???????????" | sort -u | tail -1

"???????????" --> this is to print the directories that matches the format YYMMDD_HHMM.

After this command I'm getting only.

zzz/181004_2355 

answered question

2 Answers

12

You're tailing the output of the command with tail -1. So you will only get the very last line. :)

Beyond that your command looks correct.

Couple other notes:

  1. You can write find . without the glob because find is recursive by default
  2. ??????????? could be more restrictive if you needed. ??????_???? or using [[:digit:]] would be options.

posted this
4

I'd do this natively in bash using a for loop, rather than using find.

I honestly can't remember if bash makes any promises about the order in which globs will be processed. So, using the sample date you included, here's a one-liner that compares files using [[:

$ declare -A last=(); for a in *; do for b in $a/[0-9]*; do [[ $b > $last[$a] ]] && last[$a]=$b; done; done; declare -p last
declare -A last=([bbb]="bbb/181105_0000" [zzz]="zzz/181004_2355" [aaa]="aaa/181012_1545" )

Note that the limiting patern here is $a/[0-9]*, which is sufficient for your sample data. You can of course restrict this as necessary, using character classes and eliminating the glob.

For easier reading, here's the one-liner split into multiple lines. :)

# Create an associative array. Requires bash 4+.
declare -A last=()

# Step through the top-level directories
for a in *; do
  # Step through the second level directories
  for b in "$a"/[0-9]*; do
    # Compare and record as required
    [[ $b > $last[$a] ]] && last[$a]="$b"
  done
done

# Print the result
declare -p last

posted this

Have an answer?

JD

Please login first before posting an answer.