shell 获取 目录名 当前目录名
Four ways to extract the current directory name
When you're programming a shell script, you often only need the current directory name, not the whole path that the pwd
command returns. Here are four ways you can extract only the current directory.
Using basename
Using the basename
command is the easiest and simplest way to extract the current directory:
basename /usr/local/bin bin
However, it isn't useful in a shell script with changing directory variables. You can combine it with pwd
inside backticks to make it more dynamic:
cd /usr/local/bin basename `pwd` bin
Using parameter substitution with echo
The bash scripting language is full of nice tricks, including parameter substitution, which allows you to manipulate or expand variables. You can use parameter substitution with the${var##pattern}
syntax, which removes from $var
the longest part of $Pattern
that matches the front end of $var
. Take a look at an example:
cd /var/log/squid echo ${PWD##*/} squid
PWD
is the environment variable that holds the current path, and ## is the instruction that tells the script to remove everything it finds up to */. In other words, it removes everything until the last /, leaving only the last string, which here is the current directory, squid
. You can learn more about parameter substitution and other ways to manipulate variables in the Advanced Bash-Scripting Guide.
Using awk and rev
A more elaborate solution uses a combination of awk
(a pattern-scanning utility) and rev
(a utility that reverses lines from a file or from stdin):
cd /usr/share/cups/data pwd | rev | awk –F \/ '{print $1}' | rev data
It's a lot easier to understand this kind of script step by step:
pwd /usr/share/cups/data pwd | rev atad/supc/erahs/rsu/ pwd | rev | awk –F \/ '{print $1}' atad pwd | rev | awk –F \/ '{print $1}' | rev data
The -F
option indicates that you should separate by fields, where the field delimiter is /, and that you should print field 1.
Using sed
Finally, you can parse pwd
output in the stream editor sed
using an elaborate regular expression. This approach may be educational, but it's not practical:
cd /home/smith/music pwd | sed 's,^\(.*/\)\?\([^/]*\),\2,' music
For a better understanding of how this works, remove the escape character (\), which is required for special characters such as "(":
sed 's,^(.*/)?([^/]*),\2,'
s
substitutes one string for another. It looks for two patterns, which are indicated between the first comma and the second comma. The first pattern (^(.*/)?
) searches from the beginning of the line (^) until the last occurrence that it finds of / (in the example, it matches /home/smith/
). The second pattern (([^/]*)
) searches everything from the last pattern except the / character , which is indicated by [^/]*
, where ^ at the beginning of the square brackets means not. This results in both /home/smith/
and music
. The second part of this regular expression is the substitution, indicated by \2. In sed, this is called a back reference. As its name implies, it goes back and recalls a previously used reference. There may be nine of these, named \1, \2, \3, and so on. In the example, \2 refers to the second pattern found, which is music
-- the result expected.
As you can see, Linux gives you many ways to find a directory name. Having many choices for the same chore is one of its strengths.
Sergio Gonzalez Duran is a Linux administrator, systems developer, and network security counselor who also teaches Linux courses and publishes the Spanish-oriented Linux and open source Web site linuxtotal.com.mx.