本文介绍了Bash的变量替换VS目录名称和基本名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
接下来的剧本
str=/aaa/bbb/ccc.txt
echo "str: $str"
echo ${str##*/} == $(basename $str)
echo ${str%/*} == $(dirname $str)
生产:
str: /aaa/bbb/ccc.txt
ccc.txt == ccc.txt
/aaa/bbb == /aaa/bbb
现在的问题是:
- 在的bash脚本,如果是,则建议使用命令
目录名
和基本名
键,当变量替换和为什么?
- In bash scripts, when is it recommended to use commands
dirname
andbasename
and when the variable substitutions and why?
问这主要是因为:
str="/aaa/bbb/ccc.txt"
count=10000
s_cmdbase() {
let i=0
while(( i++ < $count ))
do
a=$(basename $str)
done
}
s_varbase() {
let i=0
while(( i++ < $count ))
do
a=${str##*/}
done
}
s_cmddir() {
let i=0
while(( i++ < $count ))
do
a=$(dirname $str)
done
}
s_vardir() {
let i=0
while(( i++ < $count ))
do
a=${str%/*}
done
}
time s_cmdbase
echo command basename
echo ===================================
time s_varbase
echo varsub basename
echo ===================================
time s_cmddir
echo command dirname
echo ===================================
time s_vardir
echo varsub dirname
在我的系统产生的:
on my system produces:
real 0m33.455s
user 0m10.194s
sys 0m18.106s
command basename
===================================
real 0m0.246s
user 0m0.237s
sys 0m0.007s
varsub basename
===================================
real 0m30.562s
user 0m10.115s
sys 0m17.764s
command dirname
===================================
real 0m0.237s
user 0m0.226s
sys 0m0.007s
varsub dirname
调用外部程序(分叉)花费的时间。这个问题的主要观点是:
Calling external programs (forking) costs time. The main point of the question is:
- 是否有一些陷阱使用的变量替换,而不是外部命令?
推荐答案
的外部命令做出一些合理的修正。检查下一个脚本的结果是:
The external commands make some logical corrections. Check the result of the next script:
doit() {
str=$1
echo -e "string $str"
cmd=basename
[[ "${str##*/}" == "$($cmd $str)" ]] && echo "$cmd same: ${str##*/}" || echo -e "$cmd different \${str##*/}\t>${str##*/}<\tvs command:\t>$($cmd $str)<"
cmd=dirname
[[ "${str%/*}" == "$($cmd $str)" ]] && echo "$cmd same: ${str%/*}" || echo -e "$cmd different \${str%/*}\t>${str%/*}<\tvs command:\t>$($cmd $str)<"
echo
}
doit /aaa/bbb/
doit /
doit /aaa
doit aaa
doit aaa/
doit aaa/xxx
,结果
string /aaa/bbb/
basename different ${str##*/} >< vs command: >bbb<
dirname different ${str%/*} >/aaa/bbb< vs command: >/aaa<
string /
basename different ${str##*/} >< vs command: >/<
dirname different ${str%/*} >< vs command: >/<
string /aaa
basename same: aaa
dirname different ${str%/*} >< vs command: >/<
string aaa
basename same: aaa
dirname different ${str%/*} >aaa< vs command: >.<
string aaa/
basename different ${str##*/} >< vs command: >aaa<
dirname different ${str%/*} >aaa< vs command: >.<
string aaa/xxx
basename same: xxx
dirname same: aaa
一个最有趣的结果是 $(目录名称AAA)
。外部命令目录名
正确返回。
但变量扩展 $ {STR%/ *}
返回不正确的值 AAA
。
One of most interesting results is the $(dirname "aaa")
. The external command dirname
correctly returns .
but the variable expansion ${str%/*}
returns the incorrect value aaa
.
脚本:
doit() {
strings=( "[[$1]]"
"[[$(basename "$1")]]"
"[[${1##*/}]]"
"[[$(dirname "$1")]]"
"[[${1%/*}]]" )
printf "%-15s %-15s %-15s %-15s %-15s\n" "${strings[@]}"
}
printf "%-15s %-15s %-15s %-15s %-15s\n" \
'file' 'basename $file' '${file##*/}' 'dirname $file' '${file%/*}'
doit /aaa/bbb/
doit /
doit /aaa
doit aaa
doit aaa/
doit aaa/xxx
doit aaa//
输出:
file basename $file ${file##*/} dirname $file ${file%/*}
[[/aaa/bbb/]] [[bbb]] [[]] [[/aaa]] [[/aaa/bbb]]
[[/]] [[/]] [[]] [[/]] [[]]
[[/aaa]] [[aaa]] [[aaa]] [[/]] [[]]
[[aaa]] [[aaa]] [[aaa]] [[.]] [[aaa]]
[[aaa/]] [[aaa]] [[]] [[.]] [[aaa]]
[[aaa/xxx]] [[xxx]] [[xxx]] [[aaa]] [[aaa]]
[[aaa//]] [[aaa]] [[]] [[.]] [[aaa/]]
这篇关于Bash的变量替换VS目录名称和基本名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!