我有一个包含字符串的文件,如下所示:
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分支中有一个错误,但我现在已经没有选择了,我不知道如何得到我需要的结果。
答案 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