У меня есть два файла типа:

FILE1.TXT

1 117458 rs184574713 rs184574713
1 119773 rs224578963 rs224500000
1 120000 rs224578874 rs224500045
1 120056 rs60094200 rs60094200
2 120056 rs60094536 rs60094536

File2.txt

10  120200  120400  A   0   189,183,107
1   0       119600  C   0   233,150,122
1   119600  119800  D   0   205,92,92
1   119800  120400  F   0   192,192,192
2   120400  122000  B   0   128,128,128
2   126800  133200  A   0   192,192,192

Я хочу добавить информацию, содержащуюся во втором файле, в первый файл. Первый столбец в обоих файлах должен совпадать, а второй столбец в File1.txt должен попадать в интервал, указанный столбцами 2 и 3 в File2.txt. Чтобы результат выглядел так:

1 117458 rs184574713 rs184574713 C  0   233,150,122
1 119773 rs224578963 rs224500000 D  0   205,92,92
1 120000 rs224578874 rs224500045 F  0   192,192,192
1 120056 rs60094200 rs60094200 F    0   192,192,192
2 120440 rs60094536 rs60094536 B    0   128,128,128

Пожалуйста, помогите мне с awk / perl .. или любым другим скриптом.

0
user3560358 22 Апр 2014 в 16:37

2 ответа

Лучший ответ

Попробуйте следующее: (Учитывая тот факт, что в вашем выводе есть опечатка для последней записи. 120056 не находится между 120400 122000.

$ awk '
NR==FNR {
    a[$1,$2,$3]=$4 FS $5 FS $6;
    next
}
{
     for(x in a) {
         split(x,tmp,SUBSEP); 
         if($1==tmp[1] && $2>=tmp[2] && $2<=tmp[3]) 
             print $0 FS a[x]
      }
}' file2 file1
1 117458 rs184574713 rs184574713 C 0 233,150,122
1 119773 rs224578963 rs224500000 D 0 205,92,92
1 120000 rs224578874 rs224500045 F 0 192,192,192
1 120056 rs60094200 rs60094200 F 0 192,192,192
  • Вы читаете первый файл, создавая массив, индексированный в столбцах 1,2 и 3, со значениями столбцов 4,5 и 6.
  • Второй файл ищите в своем массиве. Для каждого ключа вы разделяете ключ и проверяете, находится ли ваше условие совпадения первого столбца и второго столбца в диапазоне.
  • Если условие истинно, вы печатаете всю строку из файла 1, за которой следует значение массива.
1
jaypal singh 22 Апр 2014 в 12:46

Вот как это сделать в bash (с небольшой помощью awk ):

join -1 1 -2 1 \
        <(sort -n -k1,1 test1) <(sort -n -k1,1 test2) | \
        awk '$2 >= $5 && $2 <= $6 {print $1, $2, $3, $4, $7, $8, $9}'

Вот краткое объяснение.

  1. Сначала мы используем join для соединения строк на основе общего ключа ( первое поле).

  2. Но join ожидает, что оба входных файла уже отсортированы (следовательно, sort).

  3. По крайней мере, мы используем awk для применения требуемого условия и для проектируем поля, которые нам нужны.

2
Roberto Reale 22 Апр 2014 в 12:46