我想比较一行到下一行,但只在第三列,从使用bash的文件

时间:2018-03-27 19:16:33

标签: bash shell while-loop

所以,我正在尝试做的是读取一个文件,循环比较它逐行比较,但只在第三列。对不起,如果这没有意义,但也许这会有所帮助。我有一个名字的文件:   JOHN SMITH SMITH JIM JOHNSON JOHNSON JIM SMITH SMITH

我想看看(首先,col3)SMITH是否等于JOHNSON,如果没有,请转到下一个名称。如果(第一个,col3)SMITH等于(second,col3)SMITH,那么我将对此做些什么。 再说一遍,如果这没有多大意义,我很抱歉,但我试着尽可能地解释它。 我试图看看他们是否平等,但显然这不起作用。这是我到目前为止所做的,但我被卡住了:

while read -a line
do
    if [ ${line[2]} == ${line[2]} ]
    then
            echo -e "${line[2]}" >> names5.txt
    else
            echo "Not equal."
    fi
done < names4.txt

2 个答案:

答案 0 :(得分:2)

将前一行存储在一个单独的变量中,以便与之进行比较:

#!/usr/bin/env bash

old_line=( )
while read -r -a line
do
    if [ "${line[2]}" = "${line[2]}" ]; then
            printf '%s\n' "${line[2]}" 
    else
            echo "Not equal." >&2
    fi
    old_line=( "${line[@]}" )
done <names4.txt >>names5.txt

注意事项的其他一些变化:

  • 不是每次想要为它写一行时重新打开names5.txt,而是在整个循环中只打开一次。 (如果你想在循环的顶部清除它并从那里追加,你可以制作这个>names5.txt。这可能是理想的行为。)
  • 我们正在避免echo -e。请参阅the POSIX standard for echo的APPLICATION USE和RATIONALE部分,了解当内容没有严格约束(例如,已知不包含任何反斜杠)时,不建议echo使用{for} {{}}的原因。
  • 我们引用了test操作的两面。这对[ ]是强制性的,以确保单词的正确操作可以扩展为globs(即,如果您有一个单词*,您不希望它被替换为您的文件列表最终命令中的当前目录),或者它们是否可以包含空格(这里没有太大关注,因为您使用与IFS相同的read -a值作为未加引号的扩展。即使使用[[ ]],您也要引用右侧,以便将其视为文字字符串,而不是模式。
  • 我们已将-r传递给read,这可确保不会以静默方式删除反斜杠(例如,将输入中的\t更改为t

答案 1 :(得分:0)

如果要将每个第三个字段与之前的所有第三个字段进行比较,则需要将旧的第三个字段存储在数组中。您可以使用awk
当您只想查看重复的第三个字段时,可以使用其他工具:

cut -d" " -f3 names4.txt | sort | uniq -d

编辑:
当你想要从连续两行打印双打时,它就更容易了:

cut -d" " -f3 names4.txt | uniq -d