Answers:
就这么简单。
(重击)
for i in * ; do mv -- "$i" "${i:0:5}" ; done
瞧
以及《高级Bash脚本指南》(第10章,操作变量)中的解释(带有额外的NOTEs内联以突出显示该手册中的错误):
子串提取
${string:position}
从提取子串
$string
的$position
。如果
$string
参数是“ *”或“ @”,则将从处提取位置参数$position
。${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.
的位置和长度的参数可以被“参数化”,即,表示为一个变量,而不是作为一个数值常数。
如果
$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.
NOTE:expr substr
是GNU扩展。
expr substr $string $position $length
$length
从$string
开始于提取字符$position
。
stringZ=abcABC123ABCabc
# 123456789......
# 1-based indexing.
echo `expr substr $stringZ 1 2` # ab
echo `expr substr $stringZ 4 3` # ABC
NOTE:这echo
是多余的,因此可靠性甚至更低。使用expr substr + "$string1" 1 2
。
NOTE:expr
如果输出为0(或-0,00 ...),则返回非零退出状态。
顺便说一句。这本书在官方Ubuntu资料库中以形式出现abs-guide
。
${var:1}
不会var
从“第一位置” 返回值,而是从第二位置返回。
在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
),也会出错并退出脚本)。如果您需要Bourne sh
兼容性,则很难可靠地进行。如果可以保证结果不会以换行符结尾,则可以执行以下操作:
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\}'`
您还将限制$var
(在系统之间变化)的长度。
在所有这些解决方案中,如果$var
包含的字节不能构成有效字符的一部分,则为YMMV。
首先,不要for
对文件名使用循环。
然后,这样的事情应该会有所帮助。
find ./ -type f | while read filename ;do
newfilename=$(echo ${filename}|cut -c 1-10)
mv ${filename} ${newfilename}
done
for
文件名使用不好?
printf
起来更安全。...和read -r
。
for
循环很好,但可能缺少它--
。在您的4行代码中,我至少可以看到10个错误!其中许多众所周知的坏习惯像假设文件名都是单行线,利用回声,缺少报价
bash
如果您要寻求sh
解决方案,为什么要加上标签?