Pie*_*e B 22 shell bash string
如何在 sh/bash 中按索引引用字符串?也就是说,基本上是分裂它。
我正在尝试删除文件名的 5 个字符。所有名称都具有以下结构:name_nr_code。我正在尝试删除 5 个字母数字代码位。name_nr_
总是 10 个字符。
有没有这样的事情?
for i in * ; do mv "$i" "$i"[:10] ; done
小智 22
就这么简单。
(重击)
for i in * ; do mv -- "$i" "${i:0:5}" ; done
Run Code Online (Sandbox Code Playgroud)
瞧。
以及高级 Bash 脚本指南(第 10 章操作变量)中的解释,(带有额外的NOTEs 内联以突出该手册中的错误):
子串提取
Run Code Online (Sandbox Code Playgroud)${string:position}
从
$string
at 中提取子字符串$position
。如果
$string
参数是“*”或“@”,那么这将提取位置参数,从 开始$position
。Run Code Online (Sandbox Code Playgroud)${string:position:length}
$length
从$string
at 中提取子字符串的字符$position
。
NOTE缺少参数扩展的引号! echo
不应用于任意数据。
stringZ=abcABC123ABCabc
# 0123456789.....
# 0-based indexing.
echo ${stringZ:0} # abcABC123ABCabc
echo ${stringZ:1} # bcABC123ABCabc
echo ${stringZ:7} # 23ABCabc
echo ${stringZ:7:3} # 23A
# Three characters of substring.
# Is it possible to index from the right end of the string?
echo ${stringZ:-4} # abcABC123ABCabc
# Defaults to full string, as in ${parameter:-default}.
# However . . .
echo ${stringZ:(-4)} # Cabc
echo ${stringZ: -4} # Cabc
# Now, it works.
# Parentheses or added space "escape" the position parameter.
Run Code Online (Sandbox Code Playgroud)
的位置和长度的参数可以被“参数化”,即,表示为一个变量,而不是作为一个数值常数。
如果
$string
参数是“*”或“@”,那么这将提取最多的$length
位置参数,从 开始$position
。
echo ${*:2} # Echoes second and following positional parameters.
echo ${@:2} # Same as above.
echo ${*:2:3} # Echoes three positional parameters, starting at second.
Run Code Online (Sandbox Code Playgroud)
NOTE:expr substr
是 GNU 扩展。
expr substr $string $position $length
Run Code Online (Sandbox Code Playgroud)
$length
从$string
开始提取字符$position
。
stringZ=abcABC123ABCabc
# 123456789......
# 1-based indexing.
echo `expr substr $stringZ 1 2` # ab
echo `expr substr $stringZ 4 3` # ABC
Run Code Online (Sandbox Code Playgroud)
NOTE: 那echo
是多余的,使它更不可靠。使用expr substr + "$string1" 1 2
.
NOTE:expr
如果输出为 0(或 -0, 00...),将返回非零退出状态。
顺便提一句。这本书在官方 Ubuntu 存储库中作为abs-guide
.
Sté*_*las 12
在 POSIX 中sh
,
"${var%?????}"
被$var
剥离的最后5个尾部字符的(或$var
如果$var
包含少于5个字符)
"${var%"${var#??????????}"}"
是 的前 10 个字符$var
。
"${var%_*}"
被$var
剥离匹配的最短串的_*
在端部$var
(foo_bar_baz
- > foo_bar
)。"${var%%_*}"
: 相同但最长的匹配而不是最短的匹配 ( foo_bar_baz
-> foo
)。foo_bar_
:"${var%"${var##*_}"}"
(${var##pattern}
是一样的${var%%pattern}
,但找之初的模式$var
,而不是末端)。与zsh
:
$var[1,-6]
用于第一个字符到最后的第 6 个字符(除最后 5 个字符外的所有字符)。$var[1,10]
前 10 个字符。与ksh
,bash
或zsh
:
"${var:0:10}"
: 的前 10 个字符 $var
与bash
或zsh
:
"${var:0:-5}"
: 除最后 5 个字符外的所有字符(如果$var
设置但包含少于 5 个字符,则给出错误并退出脚本,也$var
未设置时zsh
)。如果您需要 Bournesh
兼容性,则很难做到可靠。如果您可以保证结果不会以换行符结尾,您可以执行以下操作:
first_10=`expr " $var" : ' \(.{1,10\}\)'` # beware the exit status
# may be non-zero if the
# result is 0 or 0000000000
all_but_last_5=`expr " $var" : ' \(.*\).\{5\}'`
Run Code Online (Sandbox Code Playgroud)
您还将限制$var
(因系统而异)的长度。
在所有这些解决方案中,如果$var
包含不能构成有效字符一部分的字节,YMMV。