【问题标题】:Compter les bloc de lignes identiques [closed]Compter les bloc de lignes identiques [关闭]
【发布时间】:2023-04-08 06:40:01
【问题描述】:

你好, Je fais un script sh mais je n'arrive pas à avoir le résultat souhaité en effet j'ai un fichier texte du style

toto
tata
§
toto
tata
§
tati
§
toto

et je voudrais le résulat suivant

2 
toto
tata
1
tati
1
toto

Pour avoir les lignes uniques avec leur fréquence d'apparition, la commande:

cat file.txt | sort | uniq -c 

fonctionnait, mais comme j'ai des blocs de lignes je n'arrive pas à trouver la solution

Si quelqu'un a une idee

【问题讨论】:

  • 请标记任一 shbash,而不是两者。 bash 标签适用于一个可以,f/e,将计数器存储在一个关联数组中; sh 标签意味着不能。因此,同时使用两者会产生一个模棱两可的问题。
  • 顺便说一句,您对允许的字符有什么限制?如果你用其他东西替换你的换行符,用换行符替换你的§s,那么,你就是这样。
  • 您好。请将您的问题翻译成英文。无论好坏,SO 都希望用英语提问和回答。令人惊讶的是,AFAIK 没有一个 Stack Overflow en Français 网站。

标签: bash count sh uniq


【解决方案1】:

GNU *tools 有-z-0 选项来解析以零结尾的字符串。所以它在简单的阶段工作:

  1. 将您的§ 分隔流转换为零分隔流。
  2. 将其作为零分隔流处理。
  3. 请求输出的格式。

所以:

# convert §\n into zero byte
sed -z 's/§\n/\x00/g' |
# sort and uniq
sort -z | uniq -z -c |
# extract the number inserted by uniq and output the number with a newline
sed 's/\(^\|\x00\) *\([0-9]\+\) /\2\n/g'

输出tested on repl:

1
tati
1
toto
2
toto
tata

如果您希望计数 2 位于第一行,例如,您可以将uniq 的输出与sort 倒序排列在第一个字段上,例如:

sed -z 's/§\n/\x00/g' |
sort -z | uniq -z -c |
sort -z -n -r -k1 |
sed 's/\(^\|\x00\) *\([0-9]\+\) /\2\n/g'

哪个输出:

2
toto
tata
1
toto
1
tati

在 posix shell 上,有一种方法可以解决。首先将流转换为部分,每个部分在单独的行上,字符转换为十六进制 ascii。然后只需 sort+uniq 这些部分。然后再将 hex 转回 ascii 字符。

{
    # tokenize - extract parts between &
    part=
    while IFS= read -r line; do
        if [ "$line" != '§' ]; then
            part+="$line"$'\n'
        else
            # output part in hex
            printf "%s" "$part" | xxd -p | tr -d '\n'
            echo
            part=""
        fi
    done
    if [ -n "$part" ]; then
        printf "%s" "$part" | xxd -p | tr -d '\n'
    fi
} |
# sort + uniq
sort | uniq -c |
# output count and convert text back to ascii
while IFS=' ' read -r count text; do
    echo "$count"
    printf "%s" "$text" | xxd -r -p
done

【讨论】:

    猜你喜欢
    • 2023-02-07
    • 2022-06-14
    • 2021-07-17
    • 2022-01-12
    • 2021-11-11
    • 2020-09-06
    • 2019-03-18
    • 2022-06-15
    • 2015-08-20
    相关资源
    最近更新 更多