在我的bash脚本中,我有一个变量:
c
我想创建一个包含以下内容的字符串:
appPath="/Payload/coolApp.app"
我想我可以使用bash字符串替换运算符:
"build/ios/coolApp/"
不幸的是,我发现它并没有删除子字符串中的正斜杠。
示例脚本:
${string/substring/replacement}
我的输出变为:
appPath="/Payload/coolApp.app"
appName=${appPath/"/.app"/}
appName=${appPath/"/Payload"/}
echo "build/ios/$appName/"
我的问题:为什么不删除转发斜杠? 注意:我目前正在MacOSX 10.11.6上运行
测试解决方案脚本:
build/ios//Payload/coolApp.app/
输出:
#!/bin/sh
appPath="/Payload/coolApp.app"
appName=${appPath/"/.app"/}
appName=${appPath/"/Payload"/}
echo "Original:" "build/ios/$appName/"
appName=${appPath/"\/.app"/}
appName=${appPath/"\/Payload"/}
echo "Escape \:" "build/ios/$appName/"
v1="${appPath/\/Payload/build\ios}"
echo "heemayl:" $v1
v2="${appPath##/Payload/}"
v2="build/ios/${appPath%.app}/"
echo "redneb:" $v2
答案 0 :(得分:2)
您需要使用/
\
$ appPath="/Payload/coolApp.app"
$ echo "${appPath/\/Payload/build\/ios}"
build/ios/coolApp.app
答案 1 :(得分:2)
使用BASH_REMATCH
可以为这种情况派上用场:
appPath="/Payload/coolApp.app"
pattern='/.*/(.*)[.].*'
[[ $appPath =~ $pattern ]] && echo "build/ios/${BASH_REMATCH[1]}/"
<强>输出:强>
build/ios/coolApp/
双括号语句[[ $appPath =~ $pattern ]]
充当IF
语句,它基本上会问自己“$appPath
是否适合$pattern
?” - 如果确实如此,则回应替换。
以下是正则表达式模式的概要:
/.*/
匹配/Payload/
/ matches the character / literally
.* matches any character (except newline)
|_ Quantifier: * Between zero and unlimited times
/ matches the character / literally
(.*)
匹配coolApp
并将其捕获到BASH_REMATCH[1]
(捕获组1 )
1st Capturing group (.*)
.* matches any character (except newline)
|_ Quantifier: * Between zero and unlimited times
[.].*
将.app
和其他任何内容匹配到行尾
[.] match a single character ( character class )
|_ . the literal character .
.* matches any character (except newline)
|_ Quantifier: * Between zero and unlimited times
这可能看起来很复杂,虽然一旦你理解了模式的作用,它就开始变得有意义了。能够在regex editor内可视化模式通常也有助于学习。
答案 2 :(得分:1)
我想我可以使用bash字符串替换运算符:
${string/substring/replacement}
不幸的是我发现它并没有删除正斜杠 在子串内。
但当然它确实如此,或者至少可以做到。您只需将区分替换语法的斜杠与属于数据的斜杠区分开来:
appPath=/Payload/coolApp.app
echo ${appPath/\/Payload/build/ios}
特别注意,只有第一个斜杠或双斜杠和第二个斜杠对替换语法很重要。任何后续斜杠,例如&#34; build&#34;之间的斜杠。和&#34; ios&#34;在示例中,只是数据。
此外,你的报价有点绊倒了。此表单也会输出您想要的内容:
echo ${appPath/\/Payload/build\/ios}
但这不会:
echo "${appPath/\/Payload/build\/ios}"
那是因为替换中的第二个反斜杠也只是数据,因此替换产生build/ios\/coolApp/
。当出现在之外的双引号时,反斜杠将被视为在后续报价删除步骤中要删除的引号字符。当它出现在里面的双引号时,它本身就是一个引号字符,只有当后面跟一个需要在该上下文中转义的字符时$
,`,"
或{{ 1}}),或换行。因此,在您的情况下,它只是数据,因此在命令行扩展的报价删除阶段不会删除它。
更一般地说,您在许多不需要的地方使用引号。与许多语言不同,shell语言不依赖于引号来区分字符串与其他语法元素。事实上,它在这方面几乎没有区别。您只需要使用引号来抑制一个或多个字符的特殊含义。
答案 3 :(得分:1)
有几种方法可以让替换工作:
a='/Payload/coolApp.app'
echo "simple: ${a///Payload/build/ios}"
echo "plain : ${a//'/Payload'/build/ios}"
echo "front : ${a/#'/Payload'/build/ios}"
echo "end : build/ios/${a##*/}"
执行时会打印:
simple: build/ios/coolApp.app
plain : build/ios/coolApp.app
front : build/ios/coolApp.app
end : build/ios/coolApp.app
简单选项只需提供与参数扩展需要一样多的/
但这很令人困惑。
普通选项几乎相同,但引用了模式,这使得它更具可读性。
前面的选项使用#
(字符串的前面)来结束/
的需要。
结束选项不是替代选项,而是&#34;删除匹配的前缀模式&#34;。
它删除了截至上一个/
的所有内容。然后,所需的文本被添加到前面。
但更有用的方法是使用变量:
a='/Payload/coolApp.app'
b='/Payload/'
c='build/ios/'
a=${a/"$b"/$c}"
echo "var : ${a}"
将打印:
var : build/ios/coolApp.app
使用变量进行重复更改:
b='/Payload/' c='build/ios/'
a=${a/"$b"/$c}
echo "var1 : ${a}"
b='.app' c='/'
a=${a/"$b"/$c}
echo "var2 : ${a}"
将打印:
var1 : build/ios/coolApp.app
var2 : build/ios/coolApp/
答案 4 :(得分:0)
试试这个:
appPath="/Payload/coolApp.app"
appPath="${appPath##/Payload/}"
appPath="build/ios/${appPath%.app}/"
echo "$appPath"
打印:
build/ios/coolApp/
答案 5 :(得分:0)
如果您只想要应用名称,请使用
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter a number and click enter, continue doing this process ");
Console.WriteLine("When you finish, just click enter without giving any input");
int i = 0;
int[] numbersArray;
List<int> numbersList = new List<int>();
while (true)
{
String numInput = Console.ReadLine();
numbersList.Add(Int32.Parse(numInput));
numbersArray = numbersList.ToArray();
if (i >= 1)
{
if (numbersArray[i] < numbersArray[i - 1])
{
Console.WriteLine("Your series is not going up!");
break;
Environment.Exit(0);
}
if (numbersArray[i] > numbersArray[i - 1])
{
if (numInput == "") {
break;
}
}
}
i++;
}
Console.WriteLine("You entered this series: ");
for (int j = 0; j < numbersArray.Length; j++)
{
Console.WriteLine(" " + numbersArray[j]);
}
Console.WriteLine("The length of the series youve entered is: " + numbersArray.Length);
}
}