2014-01-15 3 views
0

У меня возникла проблема с написанием сценария bash и надеждой, что кто-то может мне помочь в этом. Я написал несколько небольших скриптов в bash раньше, поэтому я не совсем новый, но есть еще много возможностей для улучшения.Сценарий Bash для сравнения чисел в столбцах

Итак, у меня есть файл, который содержит только две колонки десятичных чисел, например:

0.46 0.68 
0.92 1.36 
1.38 2.04 
1.84 2.72 
2.3 3.4 
2.76 4.08 
3.22 4.76 
3.68 5.44 
4.14 6.12 
... 

То, что я хочу сделать, это сравнить каждое число в первом столбце с каждым номером во втором столбце и проверьте, равны ли какие-либо два числа и напечатайте этот номер, затем на экране или в файле.

Я нашел ответ, как это сделать в таблице excel, но мне было бы действительно интересно, как это сделать в bash или, возможно, с awk.

Первая проблема для меня в том, что я даже не знаю, как бы сравнить первое число со всеми остальными во втором столбце. Я предполагаю, что мне придется делать это через массивы. Я мог бы прочитать два числа командой «while read var_1 var_2», а затем мне пришлось бы каким-то образом добавить var_1 каждой строки в массив_1, то же самое для var_2 для другого array_2, а затем мне как-то придется сравнивать все элементы с каждым Другие.

Но я не знаю, как это сделать. Я надеюсь, что кто-то может мне помочь.

+0

Вы ищете строку или числовое равенство? Я имею в виду, если в столбце 1 появились «2.4», а в столбце 2 - «2.40» - равны или нет? –

+0

@ Эд Мортон: Я ищу числовое равенство, поэтому 2.4 = 2.40. –

+0

Скрипт, который вы выбрали как правильный ответ, не будет работать для вас, поскольку он тестирует равенство строк, поскольку в awk все индексы массива являются строками. –

ответ

2

Использование awk

awk 'FNR==NR {a[$1]++;next} ($2 in a) {print $2}' file file 
4.08 
1.38 

Прочитайте файл и сохранить столбец # 1 в массиве a, а затем сравнить столбец # 2 с массивом a

cat file 
0.46 0.68 
0.92 1.36 
1.38 2.04 
1.84 2.72 
2.3 3.4 
2.76 4.08 
3.22 4.76 
3.68 5.44 
4.14 6.12 
4.08 1.38 
+0

Спасибо за ваш ответ. Он отлично работает! –

1

эта линия должна работать:

awk '{a[$1]=1;b[$2]}END{for(x in b){a[x]++;if(a[x]>1)print x}}' file 

к сведению, что петли и проверьте в КОНЦЕ для исключения дублированных номеров в этом столбце. если каждый столбец имеет уникальные номера, эта часть может быть упрощена.

с примером fedorqui'S, выход:

4.08 
1.38 


cat file 
0.46 0.68 
0.92 1.36 
1.38 2.04 
1.84 2.72 
2.3 3.4 
2.76 4.08 
3.22 4.76 
3.68 5.44 
4.14 6.12 
4.08 1.38 
+0

Эй, спасибо за ваш ответ. Он работает, но номера заказов на выходе испорчены, поэтому трудно найти самое низкое значение. –

+0

@ user3197817 Почему этот ответ и Jotne дают тот же результат, один работает «отлично» один «перепутался»? – Kent

+0

Результат тот же, это правда, но порядок отличается. Выход Jotne сортируется с наименьшим номером вверху, и это для меня более удобно. –

0

Баш решение, которое работает так, как вы описали:

#!/bin/bash 

while read c1 c2 ;do 
    c1a=("${c1a[@]}" "$c1") 
    c2a=("${c2a[@]}" "$c2") 
done < numbers.txt 

for c1 in ${c1a[@]} ;do 
    for c2 in ${c2a[@]} ;do 
     [[ $c1 == $c2 ]] && echo $c1 
    done 
done 
+1

Эй, спасибо за ответ. Он работает отлично! –

1

одну строку, преобразование в один столбец, сортировать и использовать уник печатать только дубликаты:

(awk '{print $1}' test_input|sort|uniq ; awk '{print $2}' test_input|sort|uniq)|sort|uniq -d 
+0

'конвертирование в один столбец, сортировка и использование uniq' - не очень хорошая идея. что, если в одном столбце есть дубликаты? кроме awk; awk; sort; uniq' – Kent

+0

@Kent thx для комментариев, я добавил uniq, чтобы удалить дубликаты в одном столбце, но вы верны, что в цепочке есть много утилит. – JosefN

+0

Я видел 'uniq', он удаляет дубликаты в комбинации col1 и col2. я имел в виду, например, в col1 есть четыре 'foo', но в col2 нет' foo' вообще. поэтому 'foo' не должен выводиться. – Kent

0

Использование awk без чтения файла два раза.

awk '{a[$1];b[$2];for (i in b) if (i in a) {print i;delete a[i];delete b[i]}}' file 
0
awk '{ a[$1]; b[$2] } 
END{ 
    for (x in a) { 
     for (y in b) { 
      if (x+0 == y) { 
       print x 
       break 
      } 
     } 
    } 
}' file 
Смежные вопросы