我在目录中有文件夹,其中包含提供特定信息的名称。例如:
[allied]_remarkable_points_[treatment]
[nexus]_advisory_plans_[inspection]
....
所以我有一个类似于此的结构:[company]_title_[topic]
。该脚本必须将文件命名结构与脚本中的变量相匹配才能提取信息:
COMPANY='[allied]';
TITLE='remarkable points'
TOPIC='[treatment]'
文件夹不包含常量字符,因此我无法在脚本中使用索引匹配。我设法提取$TITLE
和$TOPIC
,但我无法匹配第一个字符串,因为变量会将我带回整个文件夹名称。
FOLDERNAME=${PWD##*/}
这条线让我感到悲伤:
COMPANY=`expr $FOLDERNAME : '\(\[.*\]\)'`
我试图通过放置避免贪婪行为?在正则表达式中:
COMPANY=`expr $FOLDERNAME : '\(\[.*?\]\)'`
但是一旦我这样做,就不会返回任何内容
有什么想法吗?
答案 0 :(得分:1)
Bash具有内置的字符串操作功能。
for f in *; do
company=${f%%\]*}
company=${company#\[} # strip off leading [
topic=${f##\[}
topic=${f%\]} # strip off trailing ]
:
done
构造${variable#wildcard}
从wildcard
的值中删除与variable
匹配的任何前缀,并返回结果字符串。加倍#
获得最长的通配符匹配而不是最短的匹配。使用%
选择后缀而不是前缀替换。
如果由于某种原因你确实想使用expr
,那么非贪婪的正则表达式尝试不起作用的原因是这种语法比expr
的任何相关语言都要新得多。事实上,如果你正在使用Bash,你可能根本不应该使用expr
,因为Bash为expr
有意义的每个用例提供了卓越的内置功能,一旦在遥远的过去sh
shell没有内置的正则表达式匹配和算术。
幸运的是,在这个孤立的案例中,获得非贪婪的匹配并不难。只需将正则表达式更改为方括号不匹配。
COMPANY=`expr "$FOLDERNAME" : '\(\[[^][]*\]\)'`
(结束方括号需要在否定字符类中首先出现;在任何其他位置,结束方括号关闭字符类。许多新手希望能够使用反斜杠转义,但这不是它的方式注意还添加了double quotes around the variable。)
答案 1 :(得分:1)
expr
中正则表达式匹配不需要{p> bash
。
[[ $FOLDERNAME =~ (\[[^]]*\]) ]] && COMPANY=${BASH_REMATCH[1]}
使用[^]]*
代替.*
进行括号内部分的非贪婪匹配。更大的正则表达式可以捕获所有三个部分:
[[ $FOLDERNAME =~ (\[[^]]*\])_([^_]*)_(\[[^]]*\]) ]] && {
COMPANY=${BASH_REMATCH[1]}
TITLE=${BASH_REMATCH[2]}
TOPIC=${BASH_REMATCH[3]}
}
答案 2 :(得分:0)
如果您对使用grep
没有反感,那么:
COMPANY=$(grep -Po "^\[.*?\]" $FOLDERNAME)