Shell脚本合并两个列表并删除重复项

时间:2010-06-22 17:10:02

标签: mysql shell list

我有以下代码:

get_list_a()
{
    $MYSQL -B -u $USER --passwword="$PW" $DB1 <<EOF
select name, value from mytable_a
EOF
}
get_list_b()
{
    $MYSQL -B -u $USER --passwword="$PW" $DB2 <<EOF
select name, value from mytable_b
EOF
}

get_list_a >$test.txt


现在我需要首先组合a和b并删除所有重复项(键是名称,第一列),然后将它们写入test.txt。列表a和列表b本身被假定为不同的。如果b中a和y中的x存在,使得x.name = y.name,那么我只想保留x。 我该怎么做?注意:在SQL中合并不是一个选项,因为它们位于具有不同排序规则的不同数据库中。

一个例子:
get_list_a打印

aaa bbb
ccc ddd

get_list_b打印

aaa fff
ggg hhh

我希望将以下内容写入文件:

aaa bbb
ccc ddd
ggg hhh

4 个答案:

答案 0 :(得分:1)

这些行的SQL查询是否有效? (未测试)

SELECT COALESCE(x.name,y.name),COALESCE(x.value,y.value)
FROM mytable_a AS x
FULL JOIN mytable_b AS y
ON x.name = y.name;

编辑:好的,如果它们在单独的数据库中,并且这些字段按照您在注释中指示的方式进行空格分隔,我可能会在perl或awk中使用关联数组,让x(a)中的值覆盖来自y(b)的值。这样的事情(仍未经测试):

get_list_a > x.txt
get_list_b > y.txt
cat y.txt x.txt | awk '{ data[$1] = $2; } END { for (i in data) { print i, data[i]; }}'

答案 1 :(得分:1)

仅仅为了“有趣”,这里是使用sed而不是临时文件(只是变量)的解决方案:

x=$(get_list_a) 
y=$(get_list_b)

while read name value
do 
    y=$(echo "$y" | sed "/^$name/ d")
done << EOF
$x
EOF

echo "$x"
echo "$y"

答案 2 :(得分:0)

你能更清楚地说出你的问题吗?你能给出一些你期望的简短示例输入和示例输出吗?有点不清楚你究竟在问什么。

编辑:根据你的需要,这应该可以解决问题:

get_a  > inputfile
get_b >> inputfile
perl -lne '$data{$F[0]} = $F[1] unless exists $data{$F[0]} }{ for $key (keys %data) { print "$key $data{$key}\n"}' inputfile > outputfile

}{是因为调用perl -n会导致程序(由-e给出)包含在隐式while (<STDIN>) { ... }块中。 }关闭while{打开一个新的代码块,直到隐式}

使用-l调用perl会使输入自动拆分为@F,类似于awk的$1$2等等。然后添加密钥/值对%data,除非密钥已经存在。

答案 3 :(得分:0)

您是仅在重复键或值上删除重复项吗?

命令 sort -u 删除重复项(字母u代表“唯一”)。它具有characeter开始和结束列中表示的排序键值的选项。它可以很简单(假设固定值长度或固定列格式):

get_list_a >$test.txt
get_list_b >>$test.txt
sort -u test.txt -k<startcol>,<endcol> test.txt > output.txt

当然,我宁愿在SQL中进行合并。