извлечение данных из двух списков с помощью сценария оболочки - PullRequest
0 голосов
/ 22 декабря 2011

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

email@address.com;
email2@address.com;
and so on   

Другой файл, в котором я ищу совпадение и помещаю совпадение в пустой файл, выглядит так -

12334    email@address.com;
32213    email2@address.com;

Я хочу сохранить цифры и соответствующие данные.У меня есть идея, как это должно работать, но мне нужно знать, как это реализовать.

Моя идея

#!/bin/bash
read -p "enter first file name:" file1
read -p "enter second file name:" file2
FILE_DATA=( $( /bin/cat $file1))
FILE_DATA1=( $( /bin/cat $file2))
for I in $((${#FILE_DATA[@]}))
     do 
     echo $FILE_DATA[$i] | grep $FILE_DATA1[$i] >> output.txt
     done

Я хочу, чтобы выходные данные выглядели так, но только для совпадающих адресов -

12334 email@address.com;
32213 email2@address.com;

Спасибо

Ответы [ 4 ]

4 голосов
/ 22 декабря 2011

совсем как манипулирование текстом с использованием SQL:

$ cat file1
b@address.com
a@address.com
c@address.com
d@address.com
$ cat file2
10712 e@address.com
11457 b@address.com
19985 f@address.com
22519 d@address.com
$ join -1 1 -2 2 <(sort file1) <(sort -k2 file2) | awk '{print $2,$1}'
11457 b@address.com
22519 d@address.com
  • сделать ключи отсортированными (здесь мы используем emails)
  • соединение по ключам (file1.column1, file2.column2)
  • формат вывода (используйте awk для реверса столбцов)
2 голосов
/ 22 декабря 2011

Как вы узнали о diff и comm, теперь пришло время узнать о другом инструменте в наборе инструментов Unix, join.

Join выполняет только то, что указывает название, он присоединяетсявместе 2 файла.Способ объединения основан на ключах, встроенных в файл.

Ограничение номер 1 при использовании объединения заключается в том, что данные должны быть отсортированы в обоих файлах в одном столбце.

file1
a abc
b bcd
c cde

file2
a rec1
b rec2
c rec3


join file1 file2
a abc rec1
b bcd rec2
c cde rec3

Вы можете проконсультироваться на странице справки по объединению, чтобы узнать, как уменьшить и изменить порядок столбцов вывода.например

1>join -o 1.1 2.2 file1 file2
a rec1
b rec2
c rec3

Вы можете использовать свой код для ввода имени файла, чтобы превратить его в обобщаемый скрипт.

Ваше решение, использующее конвейер внутри цикла for, будет работать для небольших наборов данных., но по мере увеличения размера данных стоимость запуска нового процесса для каждого слова, которое вы ищете, будет сокращать время выполнения.

Надеюсь, это поможет.

1 голос
/ 22 декабря 2011

Считать строку из файла file1.txt и назначить строку для переменной ADDR. grep file2.txt с содержимым var ADDR и добавьте вывод в file_result.txt.

(while read ADDR; do grep "${ADDR}" file2.txt >> file_result.txt ) < file1.txt
1 голос
/ 22 декабря 2011

Этот awk однострочный может помочь вам сделать это -

awk 'NR==FNR{a[$1]++;next}($2 in a){print $0 > "f3.txt"}' f1.txt f2.txt

NR и FNR являются встроенными переменными awk's, в которых хранятся номера строк. NR не сбрасывается в 0 при работе с двумя файлами. FNR делает. Поэтому, пока это условие выполняется, мы добавляем все в массив a. После завершения first file мы проверяем second column из second file. Если в array присутствует совпадение, мы помещаем всю строку в файл f3.txt. Если нет, то мы игнорируем это.

Использование данных из решения Кева:

[jaypal:~/Temp] cat f1.txt 
b@address.com
a@address.com
c@address.com
d@address.com
[jaypal:~/Temp] cat f2.txt 
10712 e@address.com
11457 b@address.com
19985 f@address.com
22519 d@address.com
[jaypal:~/Temp] awk 'NR==FNR{a[$1]++;next}($2 in a){print $0 > "f3.txt"}' f1.txt f2.txt 
[jaypal:~/Temp] cat f3.txt 
11457 b@address.com
22519 d@address.com
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...