use*_*976 244 string shell-script
我想删除字符串的最后一个字符,我尝试了这个小脚本:
#! /bin/sh
t="lkj"
t=${t:-2}
echo $t
Run Code Online (Sandbox Code Playgroud)
但它打印“lkj”,我做错了什么?
cuo*_*glm 255
使用bash4.2 及以上版本,您可以执行以下操作:
${var::-1}
Run Code Online (Sandbox Code Playgroud)
例子:
$ a=123
$ echo "${a::-1}"
12
Run Code Online (Sandbox Code Playgroud)
请注意,对于较旧的bash(例如,bash 3.2.5在 OS X 上),您应该在冒号之间和之后留出空格:
${var: : -1}
Run Code Online (Sandbox Code Playgroud)
ste*_*ver 139
在 POSIX shell 中,语法的${t:-2}含义有所不同 - 它扩展为tift设置且非 null 的值,否则扩展为 value 2。要通过参数扩展修剪单个字符,您可能需要的语法是${t%?}
请注意,在ksh93,bash或zsh,${t:(-2)}或${t: -2}(注意空格)是合法的,因为一个子扩张,但也有可能不是你想要的,因为它们返回的子字符串开始处的位置在2个字符的端部(即它移除了第一个字符i的字符串ijk)。
有关更多信息,请参阅 Bash 参考手册的 Shell 参数扩展部分:
小智 95
使用 sed 它应该尽可能快
sed 's/.$//'
Run Code Online (Sandbox Code Playgroud)
那么你的单一回声是echo ljk | sed 's/.$//'。
使用它,1 行字符串可以是任意大小。
Nid*_*dal 80
用于n从不使用sedOR的行中删除最后一个字符awk:
> echo lkj | rev | cut -c (n+1)- | rev
Run Code Online (Sandbox Code Playgroud)
例如,您可以one character使用以下命令删除最后一个字符:
> echo lkj | rev | cut -c 2- | rev
> lk
Run Code Online (Sandbox Code Playgroud)
来自手册rev页:
描述
rev 实用程序将指定的文件复制到标准输出,颠倒每一行中的字符顺序。如果没有指定文件,则读取标准输入。
更新:
如果您不知道字符串的长度,请尝试:
$ x="lkj"
$ echo "${x%?}"
lk
Run Code Online (Sandbox Code Playgroud)
Sté*_*las 55
一些选项取决于外壳:
t=${t%?}t=`expr " $t" : ' \(.*\).'`t=${t[1,-2]}t=${t:0:-1}t=${t:0:${#t}-1}t=${t/%?}t=${t/~(E).$/}@ {t=$1} ~~ $t *?请注意,虽然所有人都应该去除最后一个字符,但您会发现某些实现(那些不支持多字节字符的实现)会去除最后一个字节(因此如果最后一个字符是多字节的,则可能会损坏最后一个字符)。
该expr变体假定$t不会以一个以上的换行符结尾。如果结果字符串最终为0(000或什至-0具有某些实现),它还将返回非零退出状态。如果字符串包含无效字符,它也可能会产生意外结果。
Rus*_*uss 46
最便携、最短的答案几乎肯定是:
${t%?}
这适用于 bash、sh、ash、dash、busybox/ash、zsh、ksh 等。
它通过使用老式的 shell 参数扩展来工作。具体来说,%指定删除t匹配 glob 模式的参数的最小匹配后缀?(即:任何字符)。
请参阅此处的“删除最小后缀模式”以获取(更)更详细的解释和更多背景信息。另请参阅man bash“参数扩展”下的shell 文档(例如:)。
作为旁注,如果您想删除第一个字符,您可以使用${t#?}, 因为#匹配是从字符串的前面(前缀)而不是后面(后缀)开始的。
另外值得注意的是,%and 和#have%%和##versions,它们匹配给定模式的最长版本而不是最短版本。但是,在这种情况下,两者${t%%?}和${t##?}都将与它们的单个运算符执行相同的操作(因此不要添加无用的额外字符)。这是因为给定的?模式只匹配单个字符。将 a*与一些非通配符混合在一起%%,使用和会使事情变得更有趣##。
理解参数扩展,或者至少知道它们的存在并知道如何查找它们,对于编写和破译多种风格的 shell 脚本非常有用。参数扩展对许多人来说通常看起来像神秘的外壳巫毒教,因为......好吧......它们是神秘的外壳巫毒教(尽管如果你知道寻找“参数扩展”,则有很好的记录)。不过,当您被困在外壳中时,将其放在工具带中绝对是件好事。
Áng*_*gel 18
t=lkj
echo ${t:0:${#t}-1}
Run Code Online (Sandbox Code Playgroud)
你得到一个从 0 到字符串长度 -1 的子字符串。但是请注意,此减法是特定于 bash 的,不适用于其他 shell。
例如,dash甚至无法解析
echo ${t:0:$(expr ${#t} - 1)}
Run Code Online (Sandbox Code Playgroud)
例如,在 Ubuntu 上,/bin/sh是dash
小智 17
您还可以使用head打印出除最后一个字符之外的所有字符。
$ s='i am a string'
$ news=$(echo -n $s | head -c -1)
$ echo $news
i am a strin
Run Code Online (Sandbox Code Playgroud)
但不幸的是,有些版本head不包括领先的-选项。这是headOS X 附带的情况。
小智 7
一些改进。要删除多个字符,您可以添加多个问号。例如,要从变量中删除最后两个字符: $SRC_IP_MSG,您可以使用:
SRC_IP_MSG=${SRC_IP_MSG%??}
Run Code Online (Sandbox Code Playgroud)
小智 5
只是为了完成纯 bash 的一些可能用法:
#!/bin/bash
# Testing substring removal
STR="Exemple string with trailing whitespace "
echo "'$STR'"
echo "Removed trailing whitespace: '${STR:0:${#STR}-1}'"
echo "Removed trailing whitespace: '${STR/%\ /}'"
Run Code Online (Sandbox Code Playgroud)
第一个语法从字符串中获取一个子字符串,语法是
对于第二个,请注意符号,这意味着“从行尾”,语法是
${STRING:OFFSET:LENGTH} %
${STRING/PATTERN/SUBSTITUTION}
这是上面提到的两种较短的形式
echo "Removed trailing whitespace: '${STR::-1}'"
echo "Removed trailing whitespace: '${STR%\ }'"
Run Code Online (Sandbox Code Playgroud)
这里再次注意%符号,意思是 'Remove (即,替换为 '' )最短匹配模式(这里由PARAMETER末尾的转义空格'\ '表示- 这里命名为STR