Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
301 views
in Technique[技术] by (71.8m points)

unix - Tree functionality using sed and find command

find . -type d -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'

Came across this commandline on unix.com which acts as tree command in unix. I want to someone to explain what that sed command is exactly doing. i'm unable to understand the syntax

Right now i know the basic sed command syntax. I'm still getting a hang of the unix environment .

PS: Command works perfectly and The discussion was closed in that forum.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The find command is only looking for directories and printing them.

sed command is as follows:

sed -e 's;[^/]*/;|____;g;s;____|; |;g'
        ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^
         |               |
         |               replace ____| with  |
         replace everything up to the last / with ____

Let's see the command in action step by step:

Find all the directories and print its name:

$ find . -type d -print 
.
./python
./python/mytest
./python/mytest2
./python/mytest2/bk
./python/mytest2/infiles
./bash
./bash/backup
./awk
./sed

Replace everything up to the last / with ____:

  • sed -e 's;[^/]*/;|____;g' is read like this:
    • [^/]* --> get all characters as possible (*) that are different than /. Note that ^ stands for negation here.
    • / --> match a /.
    • given that block, replace it with the string |____.

See an example:

$ echo "hello/how/are/you" | sed 's;[^/]*/;;g'
you

$ echo "hello/how/are/you" | sed 's;[^/]*/;|____;g'
|____|____|____you

In this case:

$ find . -type d -print | sed -e 's;[^/]*/;|____;g'
.
|____python
|____|____mytest
|____|____mytes2
|____|____|____bk
|____|____|____infiles
|____bash
|____|____backup
|____awk
|____sed

Replace ____| with |:

$ find . -type d -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'
.
|____python
| |____mytest
| |____mytest2
| | |____bk
| | |____infiles
|____bash
| |____backup
|____awk
|____sed

We normally see sed expressions like:

sed 's/hello/bye/g'

but you can use different delimiters if you suspect / can be problematic. So in this case the delimiter is ;:

sed 's;hello;bye;g'

Finally, note that:

sed -e 's;[^/]*/;|____;g;s;____|; |;g'
        ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^
         1st command     2nd command

means that two commands are to be executed one after the other, so it is equivalent to:

sed 's;[^/]*/;|____;g' | sed 's;____|; |;g'

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...