Grep оставляет дублирующие строки вывод в txt

Вопрос или проблема

Я пытаюсь сравнить два файла и скопировать строку из File2 на основе строки, найденной в File1. Я хотел бы сохранить дубликаты строк в выходных данных, как видно в File3. Было бы хорошо, если бы порядок совпадал, если это возможно. Эта команда выводит только одно вхождение.

grep -wF -f File1.txt File2.txt > File3.txt
dog    d:\dog.fbx
cat    d:\cat.fbx

Файл 1

dog
dog
cat
cat
cat
mouse
snake
fish

Файл 2

horse  d:\horse.fbx
lion   d:\lion.fbx
monkey d:\monkey.fbx
dog    d:\dog.fbx
cat    d:\cat.fbx

Файл 3

dog    d:\dog.fbx
dog    d:\dog.fbx
cat    d:\cat.fbx
cat    d:\cat.fbx
cat    d:\cat.fbx

С помощью awk:

awk 'BEGIN{
       # читаем file2 в хешмассив
       while(getline < "file2") { 
         arr[$1]=$2
       };

       # читаем file1 и выводим содержимое хеша
       while(getline < "file1") { 
         if(arr[$1]=="") {
           continue  # нет совпадения в хеше (file2)
         };
         print $1 "    " arr[$1]
       }
     }'

Вывод:

dog    d:\dog.fbx
dog    d:\dog.fbx
cat    d:\cat.fbx
cat    d:\cat.fbx
cat    d:\cat.fbx

Одной строкой:

awk 'BEGIN{ while(getline < "file2") { arr[$1]=$2 }; while(getline < "file1") { if(arr[$1]=="") { continue }; print $1 "    " arr[$1] } }'
  • Я предполагаю, что информация о пути в file2 не содержит пробелов или табуляций.
  • Поскольку открыты только два файла, close("file2") и close("file1") опущены.

Ответ или решение

Для решения задачи, связанной с необходимостью сопоставления строк из двух текстовых файлов и копирования строк из File2 на основе совпадений со строками, найденными в File1, с сохранением дубликатов в результирующем файле File3, важно правильно выбрать инструмент и корректно задать параметры. В данном случае, использование стандартной команды grep не позволяет добиться желаемого результата, так как она по умолчанию не поддерживает повторяющиеся строки.

Теория

Команда grep предназначена для поиска строк, совпадающих с шаблоном, заданным в файле или через параметры командной строки, но не учитывает количество повторений необходимых строк в исходном файле. Она выводит только уникальные совпадения. Однако, задача требует, чтобы каждая строка из File1, которая имеет соответствие в File2, выводилась в таком же количестве, как она встречается в исходном файле.

Пример

Рассмотрим на примере:

  • File1.txt содержит:
    dog
    dog
    cat
    cat
    cat
    mouse
    snake
    fish
  • File2.txt содержит:
    horse  d:\horse.fbx
    lion   d:\lion.fbx
    monkey d:\monkey.fbx
    dog    d:\dog.fbx
    cat    d:\cat.fbx
  • Ожидаемый File3.txt должен содержать:
    dog    d:\dog.fbx
    dog    d:\dog.fbx
    cat    d:\cat.fbx
    cat    d:\cat.fbx
    cat    d:\cat.fbx

Применение

Для достижения такого результата, вместо grep, мы можем использовать awk, который является более универсальным инструментом для обработки текстов. Это позволит нам считывать данные из двух файлов и сохранять каждое их появление.

Ниже приведён вариант скрипта на awk, удовлетворяющий условию задачи:

awk 'BEGIN{
       # читаем File2 и сохраняем данные в хэш-таблицу arr
       while(getline < "File2.txt") { 
         arr[$1]=$2
       };

       # читаем File1 и выводим соответствующие строки из хэш-таблицы
       while(getline < "File1.txt") { 
         if(arr[$1]=="") {
           continue  # если совпадений в хэш-таблице нет, переход к следующей строке
         };
         print $1 "    " arr[$1]
       }
     }' > File3.txt

Детали и преимущества

  1. Чтение и хэширование данных из File2:
    awk позволяет считывать каждую строку из File2 и сохранять её в хэш-таблице arr, где ключом выступает первый элемент строки (например, "dog" или "cat"), а значением – путь к файлу, как d:\dog.fbx.

  2. Поиск и вывод на основе File1:
    Мы снова используем awk для последовательного чтения строк из File1. Если awk найдёт ключ в хэш-таблице, то он выведет строку, форматируя её в соответствии с данными из таблицы, тем самым, повторяя вывод многократно, как это требуется.

  3. Безопасность и стабильность:
    Важно отметить, что данный метод не зависит от порядка строк в файле File2. Также обеспечивается сохранение порядка строк из File1, что позволяет сохранять логику и читаемость выходного файла File3.

  4. Использование хэш-таблицы:
    Преимущество хранения данных в виде хэш-таблицы заключается в быстром и эффективном доступе к данным по ключу. Это позволяет избегать множественных проходов по данным и сокращает общее время выполнения программы.

  5. Ограничения и допущения:
    Предполагается, что пути в File2 не содержат пробелов или табуляций, что упрощает разбор строк. В случае изменения этого условия, потребуется дополнительный парсинг для корректного разделения элементов строки.

Эта методика позволяет решить поставленную задачу, используя мощные возможности awk для текстовой обработки, обеспечивая при этом нужную функциональность и эффективность.

Оцените материал
Добавить комментарий

Капча загружается...