您好我将字符串例如/bin/bash/Xorg.tar.gz传递给我的脚本
for i in $*; do
echo "$(expr match "$i" '\.*\.')"
done
我希望只返回Xorg,但它返回0,任何想法为什么?
答案 0 :(得分:1)
expr match
指令尝试匹配完整输入而不是部分输入。
但是,你可以使用内置的BASH正则表达式:
[[ "$i" =~ .*/([^./]+)\. ]] && echo "${BASH_REMATCH[1]}"
这将为您的示例参数打印Xorg
。
答案 1 :(得分:1)
你的字符串 SQLContext sqlContext = new SQLContext(sc);
DataFrame df = sqlContext.read()
.format("com.databricks.spark.csv")
.option("inferSchema", "true")
.option("header", "true")
.option("parserLib","univocity")
.load("data.csv");
似乎很奇怪(有点看起来像/bin/bash/Xorg.tar.gz
是一个目录或其他东西)但无论如何,你可以使用标准参数扩展来获得你想要的部分:
/bin/bash
首先删除上一个i=${i##*/}
i=${i%%.*}
之前的所有内容,然后删除第一个/
中的所有内容。
答案 2 :(得分:1)
立即修复(将循环放在一边):
$ expr '/path/to/Xorg.tar.gz' : '.*/\([^.]*\)'
Xorg
注意:
:
来表示正则表达式匹配操作。
expr <string> : <regex>
是符合POSIX的语法; GNU expr
也接受expr match <string> <regex>
,与您的尝试一样。 expr
隐式匹配字符串的 start ,因此必须使用.*/
来匹配上一个/
的所有内容
\([^.]*\)
用于匹配文件名组件的第一个.
以及但不包括的所有内容;请注意\
- (
和)
(捕获组分隔符)的转义,这是必需的,因为expr
仅支持(过时和有限){{3 }}秒。
使用捕获组可确保输出匹配的字符串,而默认情况下输出匹配字符的计数。。
至于您使用的正则表达式:
'\.*\.'
:\.*
匹配文字 *
字符的任何(可能为空)序列(.
)。 (\.
),隐含在字符串的开头,后跟正好1个字面.
(\.
)。
换句话说:您尝试匹配2个或更多连续的 .
个字符。 在字符串的开头,这显然不是你想要的。expr
会输出匹配字符的计数,在这种情况下为0
,因为没有匹配。那就是说,在shell循环的每次迭代中调用外部实用程序都是低效的,所以请考虑:
BRE,仅使用 shell参数扩展。
Tom Fenech's helpful answer,仅使用Bash的内置正则表达式匹配运算符=~
如果您实际上不需要shell循环并且可以使用外部实用程序使用单个命令处理所有路径,请考虑以下事项:
basename -a "$@" | cut -d'.' -f1
注意:basename -a
,用于处理多个文件名操作数,是非标准的,但GNU和BSD / macOS basename
都支持它。 < / p>
为了演示它的实际效果:
# Set positional parameters with `set`.
$ set -- '/path/to/Xorg.tar.gz' '/path/to/another/File.with.multiple.suffixes'
$ basename -a "$@" | cut -d'.' -f1
Xorg
File