Grep сохраняет повторяющиеся строки в выводе в txt.

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

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

grep -wF -f File1.txt File2.txt > File3.txt

Ниже представлен 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
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

С использованием (g)awk:

gawk 'FNR==NR{ a[i++]=$0 }
      FNR!=NR{ for(i in a) { if ($0~a[i]) print $0 }}' File1.txt File2.txt > File3.txt
  • Первый файл читается в массив a[]
  • Для второго файла тест $0~a[i] проверяет, совпадает ли строка с любым элементом, найденным в этом массиве

В командной оболочке bash, следующее может быть приемлемо.

while read; do grep -wF "$REPLY" File2.txt; done < File1.txt > File3.txt

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

Теория

Решение проблемы, описанной в вопросе, связано с уникальным подходом к обработке данных в файлах с помощью инструментов командной строки на UNIX-системах, таких как grep и awk. Основная задача состоит в том, чтобы сохранить порядок и количество повторяющихся строк из одного файла при их сравнении с другим файлом и записи результата в третий файл. Средства стандартной установки grep не позволяют нативно сохранять повторяющиеся строки, что диктует необходимость использования альтернативных инструментов или методов.

Команда grep -wF -f File1.txt File2.txt > File3.txt считывает строки из File1.txt, ищет их в File2.txt и записывает результат в File3.txt. Однако, по умолчанию grep не сохраняет дублирующиеся строки, присутствующие в File1.txt, в результате чего они исчезают в File3.txt.

Пример

Рассмотрим пример. Предположим, что у нас есть три файла.

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 следующим образом:

Желаемый File3.txt:

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

Применение

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

Решение с помощью awk:

Программирование с использованием awk позволяет более гибко обрабатывать входные данные. Скрипт gawk, обсуждаемый в вопросе, работает следующим образом:

gawk 'FNR==NR{ a[i++]=$0 }
      FNR!=NR{ for(i in a) { if ($0~a[i]) print $0 }}' File1.txt File2.txt > File3.txt
  1. В первой части FNR==NR{ a[i++]=$0 } каждой строке из File1.txt приписывается индекс в массиве a[].
  2. Второй блок FNR!=NR{ for(i in a) { if ($0~a[i]) print $0 }} проходит по элементам этого массива, сравнивая их со строками из File2.txt. Если соответствие найдено, строка выводится.

Этот метод позволяет сохранить все множественные вхождения строк из File1.txt, поддерживая их исходный порядок.

Решение с помощью bash цикла:

Другой подход предложен с использованием циклов в bash, который не требует установки дополнительного ПО, но может быть менее производительным на больших объемах данных.

while read; do grep -wF "$REPLY" File2.txt; done < File1.txt > File3.txt
  1. Команда while read последовательно считывает строки из File1.txt.
  2. Затем grep -wF "$REPLY" выполняет поиск каждой считанной строки в File2.txt.
  3. Результаты складываются в File3.txt.

Это решение сохраняет мультиточные вхождения строк из File1.txt, поддерживая желаемое поведение.

Заключение

При обработке большого объема данных и необходимости сохранения точного соответствия дублирующихся строк, выбор между awk и bash может быть обусловлен объемом работы и требованиями к производительности. awk предлагает больше гибкости и возможностей для манипуляций с текстом, но требует немного больше времени на изучение. Комбинация циклов bash является простым и элегантным решением, которое эффективно в большинстве случаев и легко интегрируется в уже существующие скрипты. Обе стратегии достойны внимания и могут быть адаптированы под конкретные нужды IT-специалиста, обладающего доступом к командной оболочке UNIX.

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

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