我有这种格式的日志:
log1,john,time,etc
log2,peter,time,etc
log3,jack,time,etc
log4,peter,time,etc
我想为格式中的每个人创建一个列表
"name"=("no.lines" "line" "line" ...)
例如:
peter=("2" "log2,peter,time,etc" "log4,peter,time,etc")
我已经有了这个结构并且知道如何创建像这样的变量
declare "${FIELD[1]}"=1
但我不知道如何增加记录的数量,如果我想创建这样的列表并将其附加到其中,我会收到错误消息。
#!/bin/bash
F=("log1,john,time,etc" "log2,peter,time,etc" "log3,jack,time,etc" "log4,peter,time,etc")
echo "${F[@]}"
declare -a CLIENTS
for LINE in "${F[@]}"
do
echo "$LINE"
IFS=',' read -ra FIELD < <(echo "$LINE")
if [ -z "${!FIELD[1]}" ] && [ -n "${FIELD[1]}" ] # check if there is already record for given line, if not create
then
CLIENTS=("${CLIENTS[@]}" "${FIELD[1]}") # add person to list of variables records for later access
declare -a "${FIELD[1]}"=("1" "LINE") # ERROR
elif [ -n "${!FIELD[1]}" ] && [ -n "${FIELD[1]}" ] # if already record for client
then
echo "Increase records number" # ???
echo "Append record"
"${FIELD[@]}"=("${FIELD[@]}" "$LINE") # ERROR
else
echo "ELSE"
fi
done
echo -e "CLIENTS: \n ${CLIENTS[@]}"
echo "Client ${CLIENTS[0]} has ${!CLIENTS[0]} records"
echo "Client ${CLIENTS[1]} has ${!CLIENTS[1]} records"
echo "Client ${CLIENTS[2]} has ${!CLIENTS[2]} records"
echo "Client ${CLIENTS[3]} has ${!CLIENTS[3]} records"
最佳答案
注意:下面使用了 namevars,一个新的 bash 4.3 特性。
首先:我强烈建议使用前缀命名数组以避免与无关变量发生冲突。因此,使用 content_
作为前缀:
read_arrays() {
while IFS= read -r line && IFS=, read -r -a fields <<<"$line"; do
name=${fields[1]}
declare -g -a "content_${fields[1]}"
declare -n cur_array="content_${fields[1]}"
cur_array+=( "$line" )
unset -n cur_array
done
}
然后:
lines_for() {
declare -n cur_array="content_$1"
printf '%s\n' "${#cur_array[@]}" ## emit length of array for given person
}
……或者……
for_each_line() {
declare -n cur_array="content_$1"; shift
for line in "${cur_array[@]}"; do
"$@" "$line"
done
}
将所有这些结合在一起:
$ read_arrays <<'EOF'
log1,john,time,etc
log2,peter,time,etc
log3,jack,time,etc
log4,peter,time,etc
EOF
$ lines_for peter
2
$ for_each_line peter echo
log2,peter,time,etc
log4,peter,time,etc
...并且,如果您真的想要您要求的格式,将列数作为显式数据,并且变量名没有安全命名空间,则很容易从一个格式转换对另一个:
# this should probably be run in a subshell to avoid namespace pollution
# thus, (generate_stupid_format) >output
generate_stupid_format() {
for scoped_varname in "${!content_@}"; do
unscoped_varname="${scoped_varname#content_}"
declare -n unscoped_var=$unscoped_varname
declare -n scoped_var=$scoped_varname
unscoped_var=( "${#scoped_var[@]}" "${scoped_var[@]}" )
declare -p "$unscoped_varname"
done
}
关于linux - 动态间接 Bash 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35607135/