Как в Linux скопировать строки, отфильтрованные по шаблону, в новый файл?

«Как в Linux скопировать строки, отфильтрованные по шаблону, в новый файл?» — вопрос из категории Linux и командная строка, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для копирования отфильтрованных строк в Linux используется комбинация команды фильтрации и перенаправления вывода (> или >>).

Основные команды и синтаксис:

  1. Использование grep (поиск по шаблону):

    # Скопировать все строки, содержащие "error", из log.txt в errors.log
    grep "error" log.txt > errors.log
    
    # Скопировать строки, НЕ содержащие "DEBUG" (инвертирование)
    grep -v "DEBUG" log.txt > filtered.log
    
    # Игнорировать регистр при поиске
    grep -i "warning" log.txt > warnings.log
    
    # Добавить отфильтрованные строки в конец существующего файла
    grep "critical" log.txt >> all_critical.log
  2. Использование awk (для сложной фильтрации по полям):

    # Скопировать строки, где 3-е поле равно "500"
    awk '$3 == "500"' access.log > server_errors.log
    
    # Скопировать строки, где 1-е поле больше 100, а 2-е содержит "POST"
    awk '$1 > 100 && $2 ~ /POST/' traffic.log > heavy_posts.log
  3. Использование sed (для фильтрации и одновременного редактирования):

    # Скопировать строки с 10 по 20 из файла
    sed -n '10,20p' data.txt > excerpt.txt
    
    # Скопировать строки, начиная с той, где найдено "START", до "END"
    sed -n '/START/,/END/p' script.sh > block.txt

Важные нюансы и best practices:

  • Перезапись vs Добавление:
    • > — создаёт новый файл или полностью перезаписывает существующий.
    • >> — создаёт файл или добавляет данные в конец существующего.
  • Экранирование: Если шаблон содержит специальные символы (например, $, *, [), их нужно экранировать обратным слэшем или заключать шаблон в одинарные кавычки '.
  • Производительность: Для очень больших файлов grep обычно быстрее sed или awk для простого поиска по шаблону.
  • Проверка: Перед выполнением команды с > полезно сначала проверить результат фильтрации, выведя его на экран:
    grep "pattern" large_file.txt | head -20  # Посмотреть первые 20 совпадений
    # Если всё верно, тогда копировать:
    grep "pattern" large_file.txt > output.txt