How to use bash to show folders that have two subf

2019-05-09 13:09发布

问题:

I use bash via Cygwin. I have a big folder (a), with many subfolders (b). These subfolders have either one or two subfolders each (c). I want to find all the subfolders (b) that have two subfolders (c) and output them.

The structure is as follows:

a
 b1
  c1 
 b2
  c1
  c2
 b3
  c1
  c2

Thus far I only know how to use find and pipe to output ALL subfolders in the main folder (a).

find . -type d > folders.txt

How can I only output all b folders that have two c folders to a text file with one folder per line? (In my example the output should be:

b2
b3

回答1:

Try doing this using awk :

cd a
find . -type d |
awk -F/ '{arr[$2]++}END{for (a in arr) {if (arr[a] == 3) print a}}'

Or using bash :

cd a
for i in */; do x=( $i/*/ ); (( ${#x[@]} == 2 )) && echo "${i%/}"; done


回答2:

There is a much simpler solution that takes advantage of the fact that the parent directory links .. from each subdirectory increase the link count of the directory by 1. A directory with no subdirectories has a link count of 2 (. and the link from its own parent by its name). Thus a directory with two subdirectories has a link count of 4:

find . -type d -links 4

It's not legal to make other hardlinks to a directory so there should be no false positives.



回答3:

There is a terrific open-source utility that will do what you want. It's called "tree", and it has a lot of useful options. It's included in most Linux distributions, but you should be able to compile for Cygwin.

You can find "tree" at: http://mama.indstate.edu/users/ice/tree/

You could also use Perl to this. It would be more flexible than a Bash shell script. Use the File::Find module in Perl (http://perldoc.perl.org/File/Find.html), which would allow you to easily do what you want. Do you have Perl installed in your Cygwin environment? Do you know Perl? Let me know if you'd like me to post a Perl script to do this.



回答4:

Try this bash script -

#!/bin/bash

cd a
for i in `pwd`/* ; do
  if [ -d "$i" ]; then
    DIR=0;
    cd $i;
    for j in * ; do
    if [ -d "$j" ]; then
    let DIR=DIR+1;
    fi
    done
    if [ $DIR -eq 2 ]; then
    echo $i;
    fi
  fi
done

Assume name of script is test.sh, you can do

$./test.sh > folder.txt


标签: bash shell awk