首页 > 试题广场 >

处理文本

[编程题]处理文本
  • 热度指数:13207 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
有一个文本文件nowcoder.txt,假设内容格式如下:
111:13443
222:13211
111:13643
333:12341
222:12123
现在需要编写一个shell脚本,按照以下的格式输出:
[111]
13443
13643
[222]
13211
12123
[333]
12341

输入描述:
1


输出描述:
1
示例1

输入

111:13443
222:13211
111:13643
333:12341
222:12123

输出

[111]
13443
13643
[222]
13211
12123
[333]
12341
#!/bin/bash declare -A array while read line; do key=$(echo "$line" | cut -d ':' -f 1) value=$(echo "$line" | cut -d ':' -f 2) if [ -n "${array[$key]}" ]; then array[$key]+="\n$value" else array[$key]=$value fi done < nowcoder.txt for key in "${!array[@]}"; do echo "[$key]" echo "${array[$key]}" done
发表于 2024-07-04 20:47:56 回复(0)
sort -t ':' -n -k1 -s | awk -F ':' '
{
    if(title!=$1){
        title=$1
        printf("[%s]\n",$1)
    }
    print($2)
}
'
这个题的关键在于冒号前按照从小到大排序,冒号后采用原本顺序,因此这个就相当于采用了稳定排序。可使用
 sort -t ':' -n -k1 -s
对冒号前的内容进行稳定排序,这样其他的部分就不会受到排序的影响,接下来就是依次打印了。

发表于 2023-10-27 20:25:36 回复(0)
# 方法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

发表于 2023-03-21 21:52:55 回复(0)
awk -F ":" '{arr[$1] = arr[$1] "\n" $2}
            END{for(i in arr) {
                printf "[" i "]";
                print arr[i]
            }}' nowcoder.txt
发表于 2022-09-20 16:41:08 回复(0)

awk关联数组基本用法,注意输出换行符即可

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
发表于 2022-08-27 21:48:38 回复(0)
awk -F: '{m[$1]= NFR==1 ? $2 : m[$1]"\n"$2} END{for(k in m)print "[" space k space "]",m[k]}'
发表于 2022-07-14 19:54:41 回复(0)
awk -F":" '{arr[$1]=arr[$1]"\n"$2}END{for(i in arr){print "["i"]",arr[i]}}' nowcoder.txt
发表于 2022-06-02 16:23:40 回复(0)
awk -F ":" '{a[$1]=a[$1]"\n"$2}END{for(x in a){print "["x"]",a[x]}}'
发表于 2022-05-10 16:54:47 回复(0)
发表于 2022-05-09 23:11:09 回复(0)
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}'
发表于 2022-04-26 04:13:47 回复(0)
cat nowcoder.txt | awk -F : '{
 arr[$1]=arr[$1] "\n" $2;
}
END{
 for(i in arr){
  print "[" i "]"arr[i];
 }
}'

发表于 2022-04-23 22:53:26 回复(0)
1.可能多了一个换行,错
sort nowcoder.txt| awk -F ":" 'BEGIN{str=""}{if($1==str){printf "%s\n",$2}else{str=$1;printf "[%s]\n%s\n",str,$2}}'

发表于 2022-04-19 15:17:36 回复(0)
cat nowcoder.txt|sort -s -k 1,1 -t ':'|awk -F: '{if(tmp!=$1) {tmp=$1;print "["tmp"]"} print $2}'

发表于 2022-03-30 19:48:49 回复(0)
方案一:
执行效率不高,写的有点啰嗦,还是分享下哈哈
let count=1
declare -a arry
while read line
do  
   arry[count++]=`echo $line|cut -d ":" -f 1`
done<nowcoder.txt

declare -a arrynew
let num=2
arrynew[1]=${arry[1]}
for((i=1;i<=count;i++))
do
   let flag=0
   for((j=1;j<num;j++))
   do       
       if [ ${arrynew[j]} -eq ${arry[i]} ]
       then         
          let flag=1         
       fi
   done 
   if [ $flag -eq 0 ]
   then
      arrynew[num++]=${arry[i]}
   fi 
   let flag=0
done
for val in ${arrynew[@]}
do
   echo "["$val"]"
   grep $val nowcoder.txt|awk -F ":" '{print $2}'
done
方案二:
for val in `cat nowcoder.txt|cut -d ":" -f 1|sort|uniq`
do
    echo "[$val]"
    cat nowcoder.txt| grep $val|awk  -F ":" '{print $2}'
done


发表于 2022-03-22 19:05:16 回复(1)
awk -F: '{if(!a[$1]){a[$1]=$2}else{a[$1]=a[$1]"\n"$2}}END{for(i in a){print "["i"]\n"a[i]}}'
发表于 2022-03-01 11:34:29 回复(0)
cat nowcoder.txt | sort -t ":" -k 1,1 -sb | awk -F ':' 'BEGIN{t=0}{if($1 != t){print "["$1"]";t=$1;print $2}else{print $2}}'
发表于 2022-01-03 19:42:03 回复(2)