如何在shell脚本中获取字符串给定位置的字符?
答案1
在 bash 中使用“参数扩展”${parameter:offset:length}
$ var=abcdef
$ echo ${var:0:1}
a
$ echo ${var:3:1}
d
相同的参数扩展可用于分配新变量:
$ x=${var:1:1}
$ echo $x
b
编辑:没有参数扩展(不是很优雅,但这就是我首先想到的)
$ charpos() { pos=$1;shift; echo "$@"|sed 's/^.\{'$pos'\}\(.\).*$/\1/';}
$ charpos 8 what ever here
r
答案2
参数扩展的替代方法是expr substr
substr STRING POS LENGTH
substring of STRING, POS counted from 1
例如:
$ expr substr hello 2 1
e
答案3
cut -c
如果变量不包含换行符,您可以执行以下操作:
myvar='abc'
printf '%s\n' "$myvar" | cut -c2
输出:
b
awk substr
是另一种 POSIX 替代方案,即使变量有换行符也能工作:
myvar="$(printf 'a\nb\n')" # note that the last newline is stripped by
# the command substitution
awk -- 'BEGIN {print substr (ARGV[1], 3, 1)}' "$myvar"
输出:
b
printf '%s\n'
是为了避免转义字符的问题:https://stackoverflow.com/a/40423558/895245例如:
myvar='\n'
printf '%s\n' "$myvar" | cut -c1
输出\
如预期。
在 Ubuntu 19.04 中测试。
答案4
这是一个可移植的 POSIX shell 变体,仅使用内置函数。
首先是一个单行代码,而不是一个更好可读的函数。
它使用此处解释的“参数扩展”:
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02
#!/bin/sh
x(){ s=$1;p=$2;i=0;l=${#s};while i=$((i+1));do r=${s#?};f=${s%"$r"};s=$r;case $i in $p)CHAR=$f&&return;;$l)return 1;;esac;done;}
x ABCDEF 3 # output substring at pos 3
echo $CHAR # output is 'C'
这里,oneliner 解释道。
#!/bin/sh
string_get_pos()
{
local string="$1" # e.g. ABCDEF
local pos="$2" # e.g. 3
local rest first i=0
local length="${#string}" # e.g. 6
while i=$(( i + 1 )); do
rest="${string#?}" # e.g. BCDEF
first=${string%"$rest"} # e.g. A
string="$rest"
case "$i" in
$pos) export CHAR="$first" && return 0 ;;
$length) return 1 ;;
esac
done
}
string_get_pos ABCDEF 3
echo $CHAR # output is 'C'