2

我有一个包含以下行的文件

a x1
b x1
q xq
c x1
b x2
c x2
n xn
c x3

我想在每行的第一个字段上进行测试,如果有匹配项,我想将匹配的行附加到第一行。输出应该看起来像

a x1
b x1 b x2
q xq
c x1 c x2 c x3
n xn

任何帮助将不胜感激

4

3 回答 3

2

要保留输入顺序:

$ awk '
{
    if ($1 in vals) {
        prev = vals[$1] " "
    }
    else {
        prev = ""
        keys[++k] = $1
    }
    vals[$1] = prev $0
}
END {
    for (k=1;k in keys;k++)
        print vals[keys[k]] 
}
' file
a x1
b x1 b x2
q xq
c x1 c x2 c x3
n xn
于 2013-10-24T20:01:29.233 回答
2

使用awk你可以这样做:

awk '{arr[$1]=arr[$1]?arr[$1] " " $0:$0} END {for (i in arr) print arr[i]}' file
n xn
a x1
b x1 b x2
c x1 c x2 c x3
q xq
于 2013-10-24T14:59:19.783 回答
1

我最终做了什么。(Ed Morton 和 Jonte 的回答显然更优雅。)

首先,我将输入文件的第一列保存在一个单独的文件中。

awk '{print $1}' input.file.txt > tmp0

然后保存输入文件,其中删除了在 $1 字段中具有重复值的行。

awk 'BEGIN { FS = "\t" }; !x[$1]++ { print $0}' input_file.txt > tmp1 

然后用重复的 $1 字段保存所有行。

awk 'BEGIN { FS = "\t" }; x[$1]++ { print $0}' input_file.txt >tmp2 

然后保存非重复文件 (tmp1) 的 $1 字段。

awk '{ print $1}' tmp1 > tmp3

我使用 for 循环将重复文件 (tmp2) 和删除的重复文件 (tmp1) 中的行拉入输出文件。

for i in $(cat tmp3)
do
if [ $(grep -w $i tmp0 | wc -l) = 1 ] #test for single instance in the 1st col of input file
then
echo "$(grep -w $i tmp1)" >> output.txt #if single then pull that record from no dupes
else
echo -e "$(grep -w $i tmp1) \t $(grep -w $i tmp2 | awk '{ 
            printf $0"\t" }; END { printf "\n" }')"   >> output.txt # if not single then pull that record from no_dupes first then all the records from dupes in a single line.
fi
done

最后删除 tmp 文件

rm tmp* # remove all the tmp files
于 2016-03-03T19:22:55.170 回答