Вопрос или проблема
Я пытаюсь сравнить два файла и скопировать строку из 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
Детали и преимущества
-
Чтение и хэширование данных из File2:
awk
позволяет считывать каждую строку из File2 и сохранять её в хэш-таблицеarr
, где ключом выступает первый элемент строки (например, "dog" или "cat"), а значением – путь к файлу, какd:\dog.fbx
. -
Поиск и вывод на основе File1:
Мы снова используемawk
для последовательного чтения строк из File1. Еслиawk
найдёт ключ в хэш-таблице, то он выведет строку, форматируя её в соответствии с данными из таблицы, тем самым, повторяя вывод многократно, как это требуется. -
Безопасность и стабильность:
Важно отметить, что данный метод не зависит от порядка строк в файле File2. Также обеспечивается сохранение порядка строк из File1, что позволяет сохранять логику и читаемость выходного файла File3. -
Использование хэш-таблицы:
Преимущество хранения данных в виде хэш-таблицы заключается в быстром и эффективном доступе к данным по ключу. Это позволяет избегать множественных проходов по данным и сокращает общее время выполнения программы. -
Ограничения и допущения:
Предполагается, что пути в File2 не содержат пробелов или табуляций, что упрощает разбор строк. В случае изменения этого условия, потребуется дополнительный парсинг для корректного разделения элементов строки.
Эта методика позволяет решить поставленную задачу, используя мощные возможности awk
для текстовой обработки, обеспечивая при этом нужную функциональность и эффективность.