У меня есть файл журнала с таким содержимым
The color is Orange then can used to binding.
The color is Black then can used to binding.
The animal Lion need to carefully.
The color is Black then can used to binding.
The animal Zebra need to carefully.
The animal Tiger need to carefully.
The animal Bee need to skip.
The color is White then can used to binding.
The color is Yellow then can used to binding.
The animal Ant need to skip.
The animal Tiger need to carefully.
The color is Red then can used to filled.
The color is Green then can used to filled.
Я хочу проверить, содержит ли строка шаблон и не существует ли она, а затем записать в другой журнал.
#!/bin/bash
source_file = "/home/user1/source/source_sample.log"
dest_file = "/home/user1/dest/dest_sample.log
#define line with pattern
pattern1 = ".*then can used to binding"
pattern2 = ".*need to carefully"
#check if line of pattern exist or not in destination file, if not then write it
grep -e "$pattern1" -e "$pattern2" $source_file >> $dest_file
Ожидаемый результат в dest_sample.log будет таким. Если строка шаблона не существует в файле назначения, запишите ее. Если он уже существует, не пишите его.
The color is Orange then can used to binding.
The color is Black then can used to binding.
The animal Lion need to carefully.
The animal Zebra need to carefully.
The animal Tiger need to carefully.
The color is White then can used to binding.
The color is Yellow then can used to binding.
мой файл журнала содержит более тысячи строк, пожалуйста, посмотрите на мой ожидаемый результат. Если строка имеет шаблон и никогда не существует в целевом файле.
Сортировка тысячи строк не составляет большого труда. Если вы не скажете нам, что порядок имеет значение, мое решение будет отвечать вашим требованиям.
порядок/последовательность не влияет, строка требования содержит шаблон и не существует в целевом файле журнала. Если файл журнала назначения уже есть, не записывайте эту строку. Посмотрите на результат 7 строк из 13 строк
Пока я не поставил отрицательный голос, см. idownvotedbecau.se/unclearquestion — попробуйте Grammarly или ChatGPT, чтобы получить более четкую версию того, что вы пытаетесь спросить. Лучше написанный вопрос даст вам более быстрые и качественные ответы. Удачи!
Простая команда egrep выполнит фильтрацию, sort -u
можно использовать для устранения дубликатов в выводе.
$ egrep '(then can used to binding|need to carefully)' input.txt | sort -u
The animal Lion need to carefully.
The animal Tiger need to carefully.
The animal Tiger need to carefully.
The animal Zebra need to carefully.
The color is Black then can used to binding.
The color is Orange then can used to binding.
The color is White then can used to binding.
The color is Yellow then can used to binding.
Строка The animal Tiger need to carefully.
уже существует, не пишите ее больше. пожалуйста, посмотрите образец файла и сравните с моим ожидаемым результатом.
@BrianCrist, это потому, что строки разные: в одной есть конечный пробел.
@jhnc, а как насчет того, что если я запущу скрипт больше времени, в результате потребуется только 7 строк из 13 строк
@BrianCrist да, большинство ответов не заметили этого требования
awk
на помощь!
$ awk '/then can used to binding|need to carefully/ && ($1=$1) && !a[$0]++' file
The color is Orange then can used to binding.
The color is Black then can used to binding.
The animal Lion need to carefully.
The animal Zebra need to carefully.
The animal Tiger need to carefully.
The color is White then can used to binding.
The color is Yellow then can used to binding.
фильтровать только совпадающие строки, нормализовать поля (избавиться от лишних пробелов) и фильтровать только уникальные записи.
awk '!/re/{next} !seen[$0]++ && NR>FNR' old input >new
?
Если файлы журналов не помещаются в памяти, вас заботит порядок строк и не заботят конечные пробелы:
(
awk '
/then can be used to binding|need to carefully/ {
sub(/[[:space:]]+$/,"")
print NR FS $0
}
' source.log | sort -k2 -u ;
awk '
/then can be used to binding|need to carefully/ {
sub(/[[:space:]]+$/,"")
print NR FS $0 RS NR FS $0
}
' destination.log
) |
sort -k2 |
uniq -f1 -u |
sort -n |
sed 's/^[0-9]* //' > new.log
cat new.log >> destination.log
awk
находит в исходном коде строки, соответствующие регулярному выражению, обрезает конечные пробелы и печатает с префиксом по номеру строки; его вывод затем дедуплицируется с помощью sort
, игнорируя номера строк (поле 1)awk
повторяет фильтрацию для пункта назначения, но печатает каждую строку дваждыawk
объединяются и повторно sort
uniq
отбрасывает дубликаты, также игнорируя номера строк
sort
восстанавливает исходный порядок файлов.sed
удаляет номер строкиЕсли файлы журналов небольшие, подход @karafka можно изменить:
awk '
!/then can be used to binding|need to carefully/ { next }
{ sub(/[[:space:]]+$/,"") }
!seen[$0]++ && NR>FNR
' destination.log source.log >new.log
cat new.log >>destination.log
отфильтровать строки, которые не соответствуют регулярному выражению
обрезать конечные пробелы
сохранить эту строку, которую видели
при первом появлении строки, если она пришла из нового ввода, распечатайте ее
добавить новые результаты в пункт назначения
Я думаю, что языковой барьер здесь создает некоторые проблемы.
Извините, если я пропущу то, что вы хотите.
Во-первых, в ваших данных есть строки, которые выглядят одинаково, но это не так; у некоторых есть пробелы в конце, а у других нет.
Я удалил пробелы перед обработкой. Если они имеют значение, просто оставьте их. В других ответах здесь есть примеры их удаления в процессе, хотя я мог бы добавить эту логику, если хотите.
Вы спрашивали, как это сделать с помощью grep
:
grep -Fxvf $dest_file $source_file | # Fixed string search
grep -E 'then can used to binding|need to carefully' >> $dest_file
Требуется два прохода.
Сначала выполняется сканирование -F
фиксированной строки -x
(точное совпадение) -v
(исключение) $source_file
с использованием строк $dest_file
в качестве -f
файла совпадающих строк. Это дает нам только строки из $source_file
НЕ в $dest_file
уже.
Направьте это на grep -E 'then can used to binding|need to carefully'
(или grep -e "$pattern1" -e "$pattern2"
), чтобы выбрать нужные строки из вывода первого grep
и добавить к $dest_file
.
Если возможно, что в $source_file
могут быть повторяющиеся новые строки, вы можете удалить дубликаты перед их добавлением в $dest_file
:
grep -Fxvf $dest_file $source_file | # Fixed string search
grep -E 'then can used to binding|need to carefully' |
sort -u >> $dest_file
Это изменит ваш порядок, если только $source_file
не имеет порядка, который вы можете воспроизвести, но вы сказали, что порядок не имеет значения.
То, что вы просили, было способом использования grep
, но awk
можно сделать это за один процесс, за один проход (каждый файл), без переупорядочения ваших данных.
awk 'NR==FNR{seen[$0]=1;next} 1==seen[$0]{next}
/then can used to binding|need to carefully/{seen[$0]=1;print}
' $dest_file $source_file >> $dest_file
Если вас не волнует порядок, вы можете просто вставить все совпадающие строки, включая дубликаты, а затем
sort | uniq
файл назначения.