Черный экран Kubuntu 19.10 после пробуждения

При наличии двух обычных текстовых файлов Unix цикл оболочки выводит

1235

, поскольку эта строка встречается в обоих файлах. Если это не так, то один из ваших файлов может быть текстовым файлом DOS. Вы можете преобразовать текстовые файлы DOS в текстовые файлы Unix с помощью утилиты dos2unix.

В вашем цикле нет ничего серьезного, учитывая тип ваших данных, кроме того факта, что он вызывает grepодин раз для каждой строки в file1. Он также будет соответствовать подстрокам, например 100в 1001, и будет, если какая-либо строка в file1содержит пробелы или табуляции,разбить эти строки на несколько слов (из-за for i in $(cat...), где $(cat...)не заключено в кавычки ).

Если вы хотите решить свою проблему таким способом (с циклом ), вам лучше

while IFS= read -r word; do
    grep -xF -e "$word" file2
done <file1

-xи -Fобъясняются позже в моем ответе, а -eозначает, что следующим аргументом является шаблон, соответствующий (, в противном случае он может быть принят как параметр командной строки, если он запускается с тире(-).

Это по-прежнему будет выполнять grepодин раз для каждой строки в file1, но будет делать это правильно.


Чтобы извлечь строки в file2, которые точно соответствуют строке в file1, без использования цикла оболочки, вы должны использовать

$ grep -xF -f file1 file2
1235

Предполагается, что file1содержит разумное количество строк, но не слишком много («слишком много» будет зависеть от объема имеющейся у вас памяти ).

Команда использует grepс -x, что приводит к совпадению только полных строк (без совпадений подстрок ), и с -F, который изменяет grepдля сравнения строк, а не совпадений с регулярными выражениями..

-f file1инструктирует grepсчитывать шаблоны (строки для сопоставления с )из file1.


Однако для действительно больших объемов данных было бы крайне неэффективно использовать grep. Вместо этого для этой задачи и с этим типом данных (отдельных слов в отдельных строках )было бы лучше выполнить операцию реляционного соединения между файлами:

$ join file1 file2
1235

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


Использованиеcomm:

$ comm -1 -2 file1 file2
1235

commтакже сравнивает отсортированные файлы и может легко обрабатывать очень большие наборы данных.По умолчанию печатает три столбца:

  1. строки, встречающиеся только в первом файле
  2. строки, встречающиеся только во втором файле
  3. строки, встречающиеся в обоих файлах

С помощью -1мы отключаем вывод первого столбца, а с помощью -2отключаем второй столбец, оставляя commдля вывода только тех строк, которые одинаковы в обоих файлах.

0
13.01.2020, 20:09
0 ответов

Теги

Похожие вопросы