将字符串中的单词与另一个字符串中的单词进行比较

时间:2016-02-11 14:11:00

标签: regex linux bash

我有一个包含字符串的文件,如下所示:

ABCEF
RFGTH
ABCEF_ABCT
DRFRF_ABCT
LOIKH
LOIKH_DEFT

我需要提取具有匹配单词的行,即使它们最后有_ABCT。

while IFS= read -r line 
do
    if [ $line == $line ];
    then 
    echo "$line"
    fi  
done < "$file"

我想要的输出是:

ABCEF
ABCEF_ABCT
LOIKH
LOIKH_DEFT

我知道我在IF分支中有一个错误,但我现在已经没有选择了,我不知道如何得到我需要的结果。

4 个答案:

答案 0 :(得分:1)

我会用awk来解决这个问题:

awk -F_ '{ ++count[$1]; line[NR] = $0 } 
END { for (i = 1; i <= NR; ++i) { split(line[i], a); if (count[a[1]] > 1) print line[i] } }' file

保留每行第一个字段的计数。每行都保存到一个数组中。处理完文件后,将打印第一部分计数大于1的所有行。

答案 1 :(得分:0)

for w in $(for wrd in $(grep -o "^[A-Z]*" abc.dat) 
    do 
      n=$(grep -c $wrd abc.dat) 
      if (( $n > 1 )) 
      then
        echo $wrd
      fi 
     done | uniq)
do
  grep $w abc.dat
done

使用grep -o提取标记“^ [A-Z] *”从行(^)的开头仅匹配A-Z(不是_)。这些令牌在同一文件中再次被搜索并计数(grep -c),如果&gt; 1收集。使用uniq,它们只被采用一次,然后我们再次在文件中搜索它们以查找所有匹配项,但只进行一次。

答案 2 :(得分:0)

这是一个使用数组和关联数组的纯Bash解决方案:

#!/bin/bash

IFS=_
declare -A seen

while read -r -a tokens
do
    # ${tokens[0]} contains the first word before the underscore.
    word="${tokens[0]}"

    if [[ "${seen[$word]}" ]]
    then
        [[ "${seen[$word]}" -eq 1 ]] && echo "$word"
        echo "${tokens[*]}"
        (( seen["$word"]++ ))
    else
        seen["$word"]=1
    fi
done < "$file"

输出:

ABCEF
ABCEF_ABCT
LOIKH
LOIKH_DEFT

答案 3 :(得分:0)

使用sed的另一个答案

    #!/bin/bash
    #set -x
    counter=1;
    while read line ; do
            ((counter=counter+1))
            var=$(sed -n -e "$counter,\$ s/$line/$line/p" file.txt)
            if [  -n "$var" ]
            then
                    echo $line
                    echo $var
            fi
    done < file.txt