【问题标题】:Finding a line that shows in a file only once查找仅在文件中显示一次的行
【发布时间】:2018-01-02 17:40:35
【问题描述】:

假设我有 100 行的文件。文件中有很多行重复,只有一行不重复。

我想找到只显示一次的行。有没有一个命令或者我必须建立一些复杂的循环如下?

到目前为止我的代码:

#!/bin/bash
filename="repeat_lines.txt"

var="$(wc -l <$filename )"
echo "length:" $var
#cp ex4.txt ex4_copy.txt
for((index=0; index < var; index++));
do
    one="$(head -n $index $filename | tail -1)"
    counter=0
        for((index2=0; index2 < var; index2++));
        do
            two="$(head -n $index2 $filename | tail -1)"
            if [ "$one" == "$two" ]; then
                counter=$((counter+1))
            fi
        done
    echo $one"is "$counter" times in the text: "
done

【问题讨论】:

    标签: linux bash file


    【解决方案1】:

    如果我正确理解了你的问题,那么

    sort repeat_lines.txt | uniq -u 应该可以解决问题。

    例如对于包含以下内容的文件:

    a
    b
    a
    c
    b
    

    它将输出c

    如需进一步参考,请参阅sort manpageuniq manpage

    【讨论】:

      【解决方案2】:

      使用标准 shell 工具 sortuniq,您得到了一个合理的答案。如果您想要便携且不需要bash 的东西,这可能就是您想要使用的解决方案。

      但另一种选择是使用 bash shell 中内置的功能。一种方法可能是使用关联数组,这是 bash 4 及更高版本的一个特性。

      $ cat file.txt
      a
      b
      c
      a
      b
      $ declare -A lines
      $ while read -r x; do ((lines[$x]++)); done < file.txt
      $ for x in "${!lines[@]}"; do [[ ${lines["$x"]} -gt 1 ]] && unset lines["$x"]; done
      $ declare -p lines
      declare -A lines='([c]="1" )'
      

      我们在这里做的是:

      1. declare -A 创建关联数组。这是我提到的 bash 4 功能。
      2. while 循环读取文件的每一行,并递增一个计数器,该计数器使用文件的一行内容作为关联数组中的键。
      3. for 循环遍历数组,删除计数器大于 1 的所有元素。
      4. declare -p 以可预测、可重复使用的格式打印数组的详细信息。您可以交替使用另一个 for 循环来逐步遍历剩余的数组元素(其中可能只有一个),以便对它们进行处理。

      请注意,此解决方案虽然适用于小文件(例如,最多几千行),但可能不适用于非常大的文件(例如,数百万行)。 Bash 在这种方式读取输入方面并不是最快的,使用数组时必须意识到内存限制。

      sort 替代方案的好处是内存优化使用磁盘上的文件来处理超大文件,但会牺牲速度。

      如果您要处理的文件只有几百行,那么很难预测哪种解决方案会更快。最后,输出的形式可能决定您选择的解决方案。 sort | uniq 管道生成标准输出列表。上面的 bash 解决方案生成与数组中的键相同的列表。否则,它们在功能上是等效的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-28
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        • 2012-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多