BASH - 判断是否存在重复行(y/n)

DMS*_*DMS 3 bash file uniq

我正在编写一个脚本来操作文本文件.

我要做的第一件事是检查是否存在重复的条目,如果存在,请询问用户是否要保留或删除它们.

我知道如果它们存在,如何显示重复的行,但我想要学习的只是得到"是否存在重复项?"这个问题的是/否答案.

只要命令完成没有问题,似乎uniq将返回0是否发现重复项.

if为了告诉我是否存在重复的行,我可以在-statement中添加什么命令?

我的文件非常简单,它只是单列中的值.

Adr*_*rth 6

我可能awk会这样做但是,为了多样化,这里有一个简短的管道来完成同样的事情:

$ { sort | uniq -d | grep . -qc; } < noduplicates.txt; echo $?
1
$ { sort | uniq -d | grep . -qc; } < duplicates.txt; echo $?
0
Run Code Online (Sandbox Code Playgroud)

sort+ uniq -d确保只有重复的行(不必相邻)被打印到stdoutgrep . -c计算那些模拟wc -l的行,1如果它不匹配(即零计数)它会返回有用的副作用并且-q只是静音输出因此它不会打印行数,因此您可以在脚本中静默使用它.

has_duplicates()
{
  {
    sort | uniq -d | grep . -qc
  } < "$1"
}

if has_duplicates myfile.txt; then
  echo "myfile.txt has duplicate lines"
else
  echo "myfile.txt has no duplicate lines"
fi
Run Code Online (Sandbox Code Playgroud)


hek*_*mgl 3

您可以awk与布尔||运算符结合使用:

# Ask question if awk found a duplicate
awk 'a[$0]++{exit 1}' test.txt || (
    echo -n "remove duplicates? [y/n] "
    read answer
    # Remove duplicates if answer was "y" . I'm using `[` the shorthand
    # of the test command. Check `help [`
    [ "$answer" == "y" ] && uniq test.txt > test.uniq.txt
)
Run Code Online (Sandbox Code Playgroud)

||仅当 awk 命令返回 1(意味着它发现了重复项)时,才会执行后面的块。

但是,为了基本理解,我还将展示一个使用if块的示例

awk 'a[$0]++{exit 1}' test.txt

# $? contains the return value of the last command
if [ $? != 0 ] ; then
    echo -n "remove duplicates? [y/n] "
    read answer
    # check answer
    if [ "$answer" == "y" ] ; then
        uniq test.txt > test.uniq.txt            
    fi
fi
Run Code Online (Sandbox Code Playgroud)

然而,它们不仅仅是[]其他编程语言中的括号。[是 bash 内置命令的同义词,test也是]它的最后一个参数。你需要阅读help [才能理解