使用 bash 脚本和 grep/awk/sed,如何将与具有单个字符分隔符的已知模式匹配的行拆分为数组,例如转换token1;token2;token3;token4
为a[0] = token1
... a[3]=token4
?
答案1
更新请注意,仅当 IFS 是单个非空白字符时才适合以这种方式创建数组和数据字符串中没有多个连续的分隔符。
有关解决此问题的方法以及类似的解决方案,请转到此Unix 和 Linux 问题...(为了更深入地了解 IFS,值得一读。
使用 bash(和其他 POSIX shell,例如 ash、ksh、zsh)的IFS
(内部字段分隔符)。
使用 IFS 可避免外部调用,它只允许嵌入空格。
# ==============
A='token0:token1:token2.y token2.z '
echo normal. $A
# Save IFS; Change IFS to ":"
SFI=$IFS; IFS=: ##### This is the important bit part 1a
set -f ##### ... and part 1b: disable globbing
echo changed $A
B=($A) ### this is now parsed at : (not at the default IFS whitespace)
echo B...... $B
echo B[0]... ${B[0]}
echo B[1]... ${B[1]}
echo B[2]... ${B[2]}
echo B[@]... ${B[@]}
# Reset the original IFS
IFS=$SFI ##### Important bit part 2a
set +f ##### ... and part 2b
echo normal. $A
# Output
normal. token0:token1:token2.y token2.z
changed token0 token1 token2.y token2.z
B...... token0
B[0]... token0
B[1]... token1
B[2]... token2.y token2.z
B[@]... token0 token1 token2.y token2.z
normal. token0:token1:token2.y token2.z
答案2
主要有两种方法。一是IFS
,由 Fred.bear 演示。这样做的优点是不需要单独的进程,但是当您的输入可能包含对 shell 有特殊含义的字符时,正确处理可能会很困难。另一种方法是使用文本处理实用程序。字段分割内置于awk
.
input="token1;token2;token3;token4"
awk -vinput="$input" 'BEGIN {
count = split(input, a, ";");
print "first field: " a[1];
print "second: field" a[2];
print "number of fields: " count;
exit;
}'
awk 在处理多个输入时特别合适。
command_producing_semicolon_separated_data |
awk -F ';' '{
print "first field: " $1;
print "second field: " $2;
print "number of fields: " NF;
}'
答案3
$ str="token1;token2;token3;token4"
$ echo $str
token1;token2;token3;token4
$ echo $str | tr ';' ' '
token1 token2 token3 token4
$ arr=( $(echo $str | tr ';' ' ') ) # Populate the tokens into an array
$ echo ${arr[0]} # Access items by index
token1
$ echo ${arr[2]}
token3
$ echo ${arr[1]}
token2
$ echo ${#arr[@]} # Length of the array
4