MST

星途 面试题库

面试题:Bash排序去重与性能优化及多场景应用

你有一个非常大的文本文件large_data.txt,每行是一个包含数字和字母混合的字符串(例如:a123b, c45d等)。要求编写一个高效的Bash脚本,先按字符串中的数字部分进行降序排序(假设每个字符串都至少包含一个数字),再去除排序后结果中的重复行。在处理过程中,要尽量减少内存占用,考虑到文件可能太大无法一次性读入内存。同时,脚本需要能适应不同分隔符(如逗号、空格等)分隔数字和字母部分的情况,在脚本执行时通过参数传入分隔符。请详细说明你的设计思路和实现代码。
11.0万 热度难度
编程语言Bash

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 逐行处理文件:由于文件过大不能一次性读入内存,采用逐行读取的方式。
  2. 提取数字并排序:使用正则表达式提取每行字符串中的数字部分,根据提取的数字进行降序排序。
  3. 去除重复行:排序后,使用 uniq 命令去除重复行。
  4. 处理分隔符:通过脚本参数传入分隔符,在提取数字时使用该分隔符。

实现代码

#!/bin/bash

if [ $# -ne 1 ]; then
    echo "Usage: $0 <separator>"
    exit 1
fi

separator=$1

# 逐行读取文件,提取数字并加上原行,然后进行排序
sort -t "$separator" -k 2 -nr -s -T /tmp <<< "$(while read line; do
    number=$(echo "$line" | grep -oE "[0-9]+" | head -n 1)
    echo "$number $line"
done < large_data.txt)" | cut -d ' ' -f 2- | uniq

代码解释

  1. 参数检查:首先检查脚本执行时是否传入了一个参数(分隔符),如果没有则提示用法并退出。
  2. 提取数字并排序
    • 使用 while read line 逐行读取 large_data.txt 文件。
    • 通过 grep -oE "[0-9]+" | head -n 1 提取每行中的第一个数字部分。
    • 将提取的数字和原行一起输出,格式为 数字 原行
    • 使用 sort 命令对输出进行排序,-t "$separator" 指定分隔符,-k 2 表示按第二个字段(即提取的数字)排序,-nr 表示降序排序,-s 表示稳定排序,-T /tmp 指定临时文件目录(用于处理大数据量时排序的临时文件存储)。
  3. 去除重复行
    • 使用 cut -d ' ' -f 2- 去除排序结果中每行开头的数字部分,只保留原行。
    • 最后使用 uniq 命令去除重复行。