什么“cd`echo $ 0 | sed's / \(。* \)\ /.*/ \ 1 /'`”在bash脚本中做什么?

时间:2018-05-03 06:19:58

标签: regex bash sed

我想了解a script written in a quantum-espresso example。在其中我找到了这个表达式:

# run from directory where this script is
cd `echo $0 | sed 's/\(.*\)\/.*/\1/'` # extract pathname

但是,我无法理解s/\(.*\)\/.*/\1/的含义。

3 个答案:

答案 0 :(得分:2)

echo $0 | sed 's/\(.*\)\/.*/\1/'

获取运行脚本的文件夹。

例如,如果您正在运行名为/home/mike/test.sh的脚本,则会为您提供/home/mike/

并且整个命令将更改为该目录。

试试这个

echo this is where we started
pwd
cd `echo $0 | sed 's/\(.*\)\/.*/\1/'` # extract pathname
echo now we are here
pwd

然后从与脚本所在目录不同的目录运行脚本。

----回答问题---

sed 's/\(.*\)\/.*/\1/'

删除路径的最后一段

试试这个

echo this/is/a/test | sed 's/\(.*\)\/.*/\1/'
echo this/is/a/test/ | sed 's/\(.*\)\/.*/\1/'
echo this/is/a/test.sh | sed 's/\(.*\)\/.*/\1/'

并且由于echo $0应该为您提供一个文件(当前脚本),整个表达式应该为您提供保存该脚本的文件夹。

至于它的工作原理,请参阅同一问题的答案:https://stackoverflow.com/a/50148667/5203563

答案 1 :(得分:2)

评论部分说这是一个路径提取器。

对正则表达式的一点解释:

s/                # sed mode

\(.*\)\/.*/       # A greedy capture group followed by a slash 
                  # '(.*)/.*', it will try to match as many characters
                  # as possible (include slashes) before the 
                  # last occurrence of '/'.
                  # A non-greedy modifier '?' will make it look for 
                  # the first occurrence of '/',
                  # as in  '(.*?)/.*'. All special charters are escaped
                  # here, I removed the '\'s for better readability.

\1/               # '\1' is referring back to the 'first capture group 
                  # in the regexp, so the 'sed' command replaces 
                  # the entire match with things between the first 
                  # pair of capturing parentheses.

答案 2 :(得分:1)

使用的正则表达式是:

(.*)\/.*
  • 在第一个捕获组(.*)中,.*在零和无限次之间匹配任何字符(行终止符除外),尽可能多次,根据需要返回(贪婪)
  • \/字面匹配字符/
  • .*在零和无限次之间匹配任何字符(行终止符除外),尽可能多次,根据需要返回(贪婪)

由于您通过工具sed使用正则表达式,因此需要转义表达式:括号()变为\(和{{1} }。 \)返回第一个捕获组。关于文件路径,它表示文件所在的目录。

因此,这个脚本获取了运行脚本的文件夹,如@ Alex028502所述。

我还推荐https://regex101.com/,这是一个允许您免费在线评估正则表达式的网站。