有一个文本文件nowcoder.txt,假设内容格式如下:
111:13443222:13211111:13643333:12341222:12123
现在需要编写一个shell脚本,按照以下的格式输出:
[111]1344313643[222]1321112123[333]12341
111:13443222:13211111:13643333:12341222:12123
[111]1344313643[222]1321112123[333]12341
1
1
111:13443 222:13211 111:13643 333:12341 222:12123
[111] 13443 13643 [222] 13211 12123 [333] 12341
declare -A map
while read line
do
arr=(${line/:/ })
map["${arr[0]}"]="${map["${arr[0]}"]}${arr[1]}\n"
done < nowcoder.txt
k=0
for i in ${!map[*]}
do
[ $k -eq 0 ] && k=1 && tmp="[$i]\n${map[$i]}" && continue
printf "[$i]\n${map[$i]}"
done
printf "$tmp" 纯awk awk -F ":" '{
if (arr[$1] == "") {
arr[$1] = $2; next
}
arr[$1] = sprintf("%s\n%s", arr[$1], $2)
} END {
for (i in arr) {
printf("[%s]\n%s\n", i, arr[i])
}
}' # 方法1: 第一时间想到的思路
# 首先得到所有的key: awk -F ':' '{print $1}' nowcoder.txt | sort | uniq
# 然后遍历所有的key,使用grep+awk打印所有的value
for each_key in $(awk -F ':' '{print $1}' nowcoder.txt | sort | uniq); do
echo "[${each_key}]"
# shellcheck disable=SC2086
# shellcheck disable=SC2013
for each_value in $(grep ${each_key} nowcoder.txt | awk -F ':' '{print $2}'); do
echo ${each_value}
done
done
# 方法2 使用字典,【注意】练手用的,不推荐,输出结果是无序的,所以测试不通过,但是其实结果是对的,供学习使用
declare -A dict
while read -r line; do
# 获取key
key=${line%:*}
value=${line#*:}
dict[${key}]=${dict[${key}]}' '$value
done < nowcoder.txt
# 遍历打印
# shellcheck disable=SC2068
for each_key in ${!dict[@]}; do
echo "[${each_key}]"
for each_value in ${dict[${each_key}]}; do
echo "$each_value"
done
done
# 方法3: 使用纯awk
# 将方法2换成使用纯awk
awk -F ':' 'BEGIN{}{
dict[$1]=dict[$1] $2 "\n"
}END{
for(each_key in dict){
printf("[%s]\n", each_key)
printf("%s", dict[each_key])
}
}' nowcoder.txt awk -v FS=':' '{
if(a[$1] == "") a[$1] = a[$1]""$2
else a[$1]=a[$1]"\n"$2
}
END{
for(i in a){
printf("[%s]\n%s\n", i, a[i])
}
}' nowcoder.txt
array=()
while read line; do
num="$(echo $line | sed -r 's#([0-9]*):[0-9]*#\1#g')"
content="$(echo $line | sed -r 's#[0-9]*:([0-9]*)#\1#g')"
eval judge=\$arr$num
if [ -z "$judge" ]; then
eval "arr$num=[\${num}]"
array=(${array[@]} $(eval "echo arr$num"))
fi
eval "arr$num=\${arr$num}\ \${content}"
done
for i in ${array[@]}; do
eval "echo \$$i"
done | sort -h | awk '{for (i=1; i<=NF; i++) print $i}'