Есть ли более быстрый способ получить этот выходной файл в Linux?

Есть ли более быстрый способ получить этот выходной файл в Linux?
cat file_1

my colour is red
my rose is red
my colour is blue
my rose id blue

cat file_2 
red
blue

cat output_file should be
my colour is red
my colour is blue

здесь я использую

cat file_2 | while read line;do cat file_1 | grep "$line" | head -1;done

здесь я пытаюсь получить самую верхнюю строку, содержащую , pattern "red" and "blue"которая присутствует вfile_2

есть ли другой способ сделать, as fast as possibleпока цикл занимает время

решение1

Вы можете использовать whileконструкцию для перебора шаблонов from file2, а затем использовать -m 1with grepдля остановки после первого совпадения on file1:

while IFS= read -r i; do grep -Fm1 "$i" file1; done <file2
  • -Fвоспринимает шаблон буквально
  • -m 1заставляет grepвыйти после первого матча

Циклы оболочки обычно неэффективны, но, учитывая небольшой список шаблонов, в данном случае их можно использовать.

Более быстрая альтернатива, xargs:

xargs -a file2 -n1 -P2 -I'{}' grep -Fm1 {} file1

Используйте больше параллельных процессов ( -P) для большего количества шаблонов.

Пример:

% while IFS= read -r i; do grep -Fm1 "$i" file1; done <file2
my colour is red
my colour is blue

% xargs -a file2 -n1 -P2 -I'{}' grep -Fm1 {} file1
my colour is blue
my colour is red

решение2

Чтобы напечатать первую строку из file_1, которая соответствует строке в file_2:

$ awk 'FNR==NR{a[$0];next} {for (line in a) if ($0~line) {print; delete a[line]}}' file_2 file_1
my colour is red
my colour is blue

При таком подходе каждый файл читается только один раз.

Как это работает

  • FNR==NR{a[$0];next}

    Это сохраняет каждую строку в file_2 как ключ в ассоциативном массиве a.

  • for (line in a) if ($0~line) {print; delete a[line]}

    Для каждой строки в file_1 мы проверяем, соответствует ли она ключу в array a. Если соответствует, мы печатаем строку и удаляем ключ.

Связанный контент