Is there a way in bash to sort my files from a directory down in depth order, for example first print the files in the present directory, then the files in the sub directory or sub directories and so forth, always in perspective to their depth.
Bash Sort Files Alphabetically By default, the ls command lists files in ascending order. To reverse the sorting order, pass the -r flag to the ls -l command, like this: ls -lr . Passing the -r flag to the ls -l command applies to other examples in this tutorial.
the -r flag is an option of the sort command which sorts the input file in reverse order i.e. descending order by default. Example: The input file is the same as mentioned above. 3. -n Option: To sort a file numerically used –n option.
The easiest way to list files by name is simply to list them using the ls command. Listing files by name (alphanumeric order) is, after all, the default. You can choose the ls (no details) or ls -l (lots of details) to determine your view.
To sort files in a different order, click the view options button in the toolbar and choose By Name, By Size, By Type, By Modification Date, or By Access Date. As an example, if you select By Name, the files will be sorted by their names, in alphabetical order.
Use find's "-printf" feature in combination with sort. See for yourself:
find . -printf "%d %p\n"|sort -n
It generates a depth-sorted list (displaying the depth in the first column, file path in the second). This prints in my current dir:
0 .
1 ./bin
1 ./log
1 ./templates
2 ./bin/cc_env
3 ./files/test/mail.txt
If you want to strip the first column, we can use perl:
find . -printf "%d %p\n"|sort -n|perl -pe 's/^\d+\s//;'
and off you go. The perl filter will remove all leading numbers. In case you want to omit directories themselves, use the '-type f' parameter:
find . -type f -printf "%d %p\n"|sort -n|perl -pe 's/^\d+\s//;'
Hint: Study the find manpage for more printf %d-like tricks.
The simplest solution:
$ echo * */* */*/* */*/*/* */*/*/*/* */*/*/*/*/*
a a/b a/b/c a/b/c/d1 a/b/c/d2 a/b/c/d1/e a/b/c/d2/e a/b/c/d1/e/f a/b/c/d2/e/f
Or, in column:
$ echo * */* */*/* */*/*/* */*/*/*/* */*/*/*/*/* |tr ' ' '\n'
a
a/b
a/b/c
a/b/c/d1
a/b/c/d2
a/b/c/d1/e
a/b/c/d2/e
a/b/c/d1/e/f
a/b/c/d2/e/f
The depth of the tree is hardcoded in the example, but you can write a small script and make it more flexible:
A="*"
while true
do
B=$(echo $A)
[ "$B" = "$A" ] && break
echo $B
A="$A/*"
done | tr ' ' '\n'
Example of usage:
$ A="*"; while true; do B=$(echo $A); [ "$B" = "$A" ] && break; echo $B; A="$A/*"; done | tr ' ' '\n'
a
a/b
a/b/c
a/b/c/d1
a/b/c/d2
a/b/c/d1/e
a/b/c/d2/e
a/b/c/d1/e/f
a/b/c/d2/e/f
Examples are provided for the tree:
$ mkdir -p a/b/c/d{1,2}/e/f
$ tree .
.
└── a
└── b
└── c
├── d1
│ └── e
│ └── f
└── d2
└── e
└── f
9 directories, 0 files
Find/depth solutions will obviously not work because find
will shows subtrees one after another. The -depth
key says in which direction subtree must be shown. But that doesn't mean, of course, that the output will be sorted by depth.
$ find .
.
./a
./a/b
./a/b/c
./a/b/c/d2
./a/b/c/d2/e
./a/b/c/d2/e/f
./a/b/c/d1
./a/b/c/d1/e
./a/b/c/d1/e/f
$ find . -depth
./a/b/c/d2/e/f
./a/b/c/d2/e
./a/b/c/d2
./a/b/c/d1/e/f
./a/b/c/d1/e
./a/b/c/d1
./a/b/c
./a/b
./a
.
As you can see the answer is incorrect in both cases (with and without -find
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With