如何通过管道传输字符串并从中删除一些字符?,例如:
$ echo forbes | ... -3
for
$ echo cucumber | ... -4
cucu
$ echo 1461624333 | .. -3
1461624
...
etc.
我找不到在管道中使用
${str:0:-3}
语法的方法。
通过管道传输到 sed:
$ echo forbes | sed 's/...$//'
for
这会匹配字符串的最后三个字符并将其删除(用空字符串替换)。
要参数化要删除的字符数,我们可以将其包装在一个小函数中:
pipesubstr () {
sed "s/.\{$1\}$//"
}
使用方法如下:
$ echo forbes | pipesubstr 3
for
$ echo cucumber | pipesubstr 4
cucu
$ echo 1461624333 | pipesubstr 3
1461624
使用
cut
?
$ echo "forbes" | cut -b 1-3
for
更新:
要从后面刮胡子,您可以这样做:
echo "forbes" | rev | cut -c (n+1)- | rev
其中
n
是您想要从末尾开始删除的字符数
echo "forbes" | rev | cut -c 4- | rev
for
GNU
head
是另一种选择(从输入字符串中删除最后 N 个字符作为一个整体 - 即使它跨越多行):
# GNU `head` only (doesn't work with the `head` that comes with macOS)
# CAVEAT: -c operates on *bytes*, not characters.
$ printf '1461624333' | head -c -3 # drop last 3 chars.
1461624
请注意,如果您使用
echo
而不是 printf
,则必须考虑尾随 \n
,因此您必须将 1
添加到计数中(并且输出不会有尾随 \n
)。
警告:
head -c
,尽管选项名称很短,但操作于字节而不是字符,因此仅适用于单字节编码,例如 ASCII 和扩展 ASCII 变体(例如,ISO-8859=1),因此不可靠地使用UTF-8:只有当最后 N 个字符恰好都是 ASCII 范围字符时,结果才会符合预期。--bytes
,使这个限制更加明显。
顺便说一句:
brew install coreutils
g
前缀(例如 ghead
)安装它们,以免覆盖内置实用程序,但您可以按照安装时打印的说明中的说明修改 PATH
来覆盖后者。 awk
解决方案(从输入中的每一行中删除最后一个
n
字符):
$ echo '1461624333' | awk -v n=3 '{ print substr($0, 1, length($0)-n) }' # drop last 3
1461624
警告: 并非所有 awk
实现都支持区域设置;例如,OS X 10.11.4 上的 BSD
awk
不是:
$ echo 'usä' | awk -v n=1 '{ print substr($0, 1, length($0)-n) }'
us? # !! on OSX, mistakenly returns the first byte of multi-byte UTF8 char. 'ä'