我遇到了ss64.com,它为如何编写Windows命令解释器将运行的批处理脚本提供了很好的帮助.
但是,我一直无法找到批处理脚本的语法,扩展或不扩展的方法,以及如何逃避事情的良好解释.
以下是我无法解决的示例问题:
foreach $i (@ARGV) { print '*' . $i ; }
),编译它并以这种方式调用它:
my_script.exe "a ""b"" c"
?输出是 *a "b*c
my_script.exe """a b c"""
?输出它*"a*b*c"
echo
命令如何工作?在那个命令中扩展了什么?for [...] %%I
在文件脚本中使用,但for [...] %I
在交互式会话中?%PROCESSOR_ARCHITECTURE%
字面回声?我发现echo.exe %""PROCESSOR_ARCHITECTURE%
有效,有没有更好的解决方案?%
配对?例:
set b=a
,echo %a %b% c%
?%a a c%
set a =b
,echo %a %b% c%
?bb c%
或者更一般地说,如何从Bash环境变量中以冒号分隔的列表中删除项?
我想我多年前已经看到了一种简单的方法,使用更高级的Bash变量扩展形式,但如果是这样的话,我已经忘记了它.对谷歌的快速搜索出乎意料地少了几个相关结果,没有一个我称之为"简单"或"优雅".例如,分别使用sed和awk的两种方法:
PATH=$(echo $PATH | sed -e 's;:\?/home/user/bin;;' -e 's;/home/user/bin:\?;;')
PATH=!(awk -F: '{for(i=1;i<=NF;i++){if(!($i in a)){a[$i];printf s$i;s=":"}}}'<<<$PATH)
Run Code Online (Sandbox Code Playgroud)
什么都不直接存在?有什么类似于Bash中的split()函数吗?
更新:
看起来我需要为我的故意模糊的问题道歉; 我对解决特定用例的兴趣不如激发良好的讨论.幸运的是,我明白了!
这里有一些非常聪明的技巧.最后,我在工具箱中添加了以下三个功能.魔法发生在path_remove中,这主要基于Martin York巧妙使用awk
的RS变量.
path_append () { path_remove $1; export PATH="$PATH:$1"; }
path_prepend () { path_remove $1; export PATH="$1:$PATH"; }
path_remove () { export PATH=`echo -n $PATH | awk -v RS=: -v ORS=: '$0 != "'$1'"' | sed 's/:$//'`; }
Run Code Online (Sandbox Code Playgroud)
唯一真正的缺点是使用sed
去除尾部结肠.考虑到马丁的其他解决方案是多么简单,但我非常愿意接受它!
相关问题: 如何在shell脚本中操作$ PATH元素?
我有一个Bash变量,$word
有时候是一个单词或句子,例如:
word="tiger"
Run Code Online (Sandbox Code Playgroud)
要么:
word="This is a sentence."
Run Code Online (Sandbox Code Playgroud)
如何创建一个新的Bash变量,该变量仅等于变量中的第一个字母?例如,以上将是:
echo $firstletter
t
Run Code Online (Sandbox Code Playgroud)
要么:
echo $firstletter
T
Run Code Online (Sandbox Code Playgroud) 关于性能,做什么之间有什么区别:
$message = "The request $request has $n errors";
Run Code Online (Sandbox Code Playgroud)
和
$message = sprintf('The request %s has %d errors', $request, $n);
Run Code Online (Sandbox Code Playgroud)
用PHP?
我会说调用函数涉及更多的东西,但我不知道PHP在幕后扩展变量名称是做什么的.
谢谢!
#!/bin/sh
for i in {1..5}
do
echo "Welcome"
done
Run Code Online (Sandbox Code Playgroud)
会工作,显示欢迎5次.
#!/bin/sh
howmany=`grep -c $1 /root/file`
for i in {1..$howmany}
do
echo "Welcome"
done
Run Code Online (Sandbox Code Playgroud)
Doesn't work! howmany
would equal 5 as that is what the output of grep -c
would display. $1 is parameter 1 which is specific when running the script.
Any ideas?
我试图在命令调用中扩展变量.这就是我的意思.vimrc
:
command! -nargs=1 -complete=dir TlAddPm call s:TlAddPm(<f-args>)
function! s:TlAddPm(dir)
let flist = system("find " . shellescape(a:dir) . " -type f -name '*.pm' | sort")
TlistAddFiles `=flist`
endfun
Run Code Online (Sandbox Code Playgroud)
在:
提示符下,`=flist`
语法似乎起作用(或者,至少它使用w:
变量),但在.vimrc
文件中它没有--TlistAddFiles只是传递字符串`=flist`
.
感谢Andrew Barnett和Mykola Golubyev的回答,我现在得到了这个,这似乎有效.有没有更好的方法?
command! -nargs=1 -complete=dir TlAddPm call s:TlAddPm(<f-args>)
function! s:TlAddPm(dir)
let findres = system("find " . shellescape(a:dir) . " -type f -name '*.pm' | sort")
let flist = []
for w in split(findres, '\n')
let flist += [ fnameescape(w) …
Run Code Online (Sandbox Code Playgroud) 如何$pw
在单引号内扩展?
$pw = "$PsHome\powershell.exe"
cmd.exe /c 'schtasks /create /tn cleanup /tr "$pw -WindowStyle hidden -ExecutionPolicy Bypass -nologo -noprofile %TEMP%\exec.ps1" /sc minute /mo 1'
Run Code Online (Sandbox Code Playgroud) (编辑:基于@Michael反馈的问题更准确)
在bash中,我经常使用参数扩展:以下命令default value
在$VARNAME
未设置时打印" " ,否则打印VARNAME内容.
echo ${VARNAME:-default value} #if VARNAME empty => print "default value"
echo ${VARNAME-default value} #if VARNAME empty => print "" (VARNAME string)
Run Code Online (Sandbox Code Playgroud)
我没有在GNU上找到类似的功能make
.我终于在我写的Makefile
:
VARNAME ?= "default value"
all:
echo ${VARNAME}
Run Code Online (Sandbox Code Playgroud)
但我对这个解决方案不满意:它总是创建变量VARNAME
,这可能会改变某些makefile上的行为.
有没有更简单的方法来获取未设置变量的默认值?
在我问之前,我做了一些谷歌搜索,但无法找到答案.
我的方案是:将一个数字列表传递给脚本,通过文件分隔\n,或通过命令行arg以逗号分隔.数字可以是单数,也可以是块,如下所示:
文件:
1
2
3
7-10
15
20-25
Run Code Online (Sandbox Code Playgroud)
命令行Arg:
1, 2, 3, 7-10, 15, 20-25
Run Code Online (Sandbox Code Playgroud)
两者最终都在同一个列表中[].我想扩展7-10或20-25块(显然在实际脚本中这些数字会有所不同)并将它们附加到一个新列表中,最终列表如下所示:
['1','2','3','7','8','9','10','15','20','21','22','23','24','25']
Run Code Online (Sandbox Code Playgroud)
我理解像.append(range(7,10))这样的东西可以帮助我,但我似乎无法找出原始列表[]中哪些元素需要扩展.
所以,我的问题是:给定一个列表[]:
['1','2','3','7-10','15','20-25'],
Run Code Online (Sandbox Code Playgroud)
如何获得列表[]:
['1','2','3','7','8','9','10','15','20','21','22','23','24','25']
Run Code Online (Sandbox Code Playgroud) 我的 bash 脚本中有一些变量可能包含文件名或未设置。它们的内容应作为附加参数传递给程序。但是当变量未设置时,这会留下一个空参数。
$ afile=/dev/null
$ anotherfile=/dev/null
$ unset empty
$ cat "$afile" "$empty" "$anotherfile"
cat: : No such file or directory
Run Code Online (Sandbox Code Playgroud)
如果没有引号,它就可以正常工作,因为附加参数被简单地省略了。但由于变量可能包含空格,因此必须在此处用引号引起来。
我知道我可以简单地将整条线包装在对空性的测试中。
if [ -z "$empty" ]; then
cat "$afile" "$anotherfile"
else
cat "$afile" "$empty" "$anotherfile"
fi
Run Code Online (Sandbox Code Playgroud)
但对每个变量进行一次测试会产生一棵巨大而复杂的决策树。
有没有更紧凑的解决方案?bash 可以省略带引号的空变量吗?
bash ×5
variables ×2
arguments ×1
batch-file ×1
cmd ×1
gnu-make ×1
list ×1
parsing ×1
path ×1
performance ×1
php ×1
powershell ×1
printf ×1
python ×1
python-2.7 ×1
shell ×1
string ×1
syntax ×1
vim ×1
windows ×1