【发布时间】:2018-06-04 11:14:41
【问题描述】:
我想删除最后一个字符之前的 4 个字符。
输入:
abc2a982
e1kei9e5bc5
e1edeaww58476
预期输出:
abc2
e1kei95
e1edeaww6
到目前为止我已经尝试过:
cat file | while read line; do echo $line | sed 's/.\{4}$\1/';done
我想应该有别的东西而不是\1。
【问题讨论】:
我想删除最后一个字符之前的 4 个字符。
输入:
abc2a982
e1kei9e5bc5
e1edeaww58476
预期输出:
abc2
e1kei95
e1edeaww6
到目前为止我已经尝试过:
cat file | while read line; do echo $line | sed 's/.\{4}$\1/';done
我想应该有别的东西而不是\1。
【问题讨论】:
如果您想单独使用 bash 并避免使用 sed,您可以使用 parameter expansion 来操作您的字符串。
while read -r line; do
allbutlast1="${line%?}" # strip the last character from $line
lastchar="${line#$allbutlast1}" # strip what we just captured from start of line
allbutlast5="${line%?????}" # strip the last 5 characters
printf '%s%s\n' "$allbutlast5" "$lastchar"
done
或者如果你使用 bash 作为你的 shell,你有 additional options:
while read -r line; do
printf '%s%s\n' "${line:0:$(( ${#line} - 5))}" "${line:$(( ${#line} - 1 ))}"
done
(压缩 bash 代码以保存丢弃的变量。)
POSIX 代码(第一个示例)使用参数扩展 ${var%...} 和 ${var#...} 来构造输出。 Bash 代码使用${var:start:length} 表示法,带有arithmetic expansion、$(( ... ))。
此答案主要用于学术目的。与使用 shell 脚本逐行处理输入相比,使用 awk 或 sed 可以获得更好的性能。
说起来,awk 解决方案可能反映了 bash 解决方案:
awk '{print substr($0,1,length($0)-5) substr($0,length($0))}'
请注意,虽然 bash 的 ${var:start:length} 表示法从零开始编号字符,但 awk 的 substr() 函数从一开始。
【讨论】:
printf '%s%s\n' "${line:0:-5}" "${line:(-1)}"。
% cat input | sed 's/....\(.\)$/\1/'
abc2
e1kei95
e1edeaww6
【讨论】:
's/....\(.\)$/\1/' 在功能上等同于 's/\(.\)\(.\)\(.\)\(.\)\(.\)$/\5/'。