Используя wget и grep для загрузки страниц HTML и фильтра ключевыми словами

Оболочки имеют подстановочные символы, которые отличаются от обычных regexp синтаксисов: ? соответствовать любому отдельному символу, * соответствовать любому количеству символов, и [abc] соответствовать любому отдельному символу среди a, b или c. Следующая команда показывает все файлы, имя которых соответствует расширенному регулярному выражению ¹ ((R|r)eading(T|t)est(D|d)ata) в текущем каталоге:

echo *[Rr]eading[Tt]est[Dd]ata*

Если Вы хотите найти файлы в подкаталогах также, то первый показ shopt -s globstar (можно вставить эту команду Ваш ~/.bashrc). Это включает ** шаблон для соответствия любому уровню подкаталогов:

echo **/*[Rr]eading[Tt]est[Dd]ata*

Подстановочные символы Shell не так мощны как регулярные выражения. Например, существует не или (|) оператор. Можно получить питание регулярных выражений, но с другим синтаксисом по историческим причинам. Добавить shopt -s exgblob к Вашему .bashrc, затем можно использовать @(foo|bar) соответствовать foo или bar (как foo|bar в ДО), *(pattern) соответствовать последовательности любое количество случаев pattern (как (pattern)* в ДО), +(pattern) соответствовать одним или нескольким случаям, ?(pattern) соответствовать нулю или одному возникновению, и !(pattern) соответствовать чему-либо кроме pattern (не ДО эквивалент).

¹ “Расширенное регулярное выражение” (ДО, если коротко) название Unix regex синтаксиса, который использует JavaScript.

2
14.01.2014, 07:45
4 ответа
KEYWORDS=("dolphins" "fish" "dogs" "cats" "iguanas")
IFS=$'\n'
find . -type f ! -exec grep -qF "${KEYWORDS[*]}" {} \; -exec rm -f {} \;

Удалил бы файлы, которые не имеют ни одного из ключевых слов.

2
27.01.2020, 22:00
  • 1
    хорошо, проблемой является... wget... –  Braiam 14.01.2014, 00:54
  • 2
    = ("дельфины" "ловят" "кошек" "собак" "игуаны") $ IFS= '\n' находят. - тип f - размер +1c! - должностное лицо grep - скорострельный "$ {КЛЮЧЕВЫЕ СЛОВА [*]}" {} \; - должностное лицо усекают-s 0-f {} \;----------------------------------я хотел бы использовать Ваше решение, но добавить следующее: Если файл является более чем 1-байтовым поиском ключевых слов, еще пропускают файл..., если ключевое слово не найдено усеченным к 0bytes. Я получаю следующую ошибку: усеченный: недопустимая опция - 'f' Попытка, 'усеченная - помогает' для получения дополнительной информации. –  Guest in need of help 14.01.2014, 06:32
  • 3
    Удалите -f. –  Stéphane Chazelas 14.01.2014, 09:38

При использовании расширенный или регулярные выражения Perl, grep может взять несколько шаблонов поиска, разделенных каналом (|):

   -E, --extended-regexp
          Interpret  PATTERN  as  an extended regular expression (ERE, see
          below).  (-E is specified by POSIX.)

   -P, --perl-regexp
          Interpret  PATTERN  as  a  Perl  regular  expression  (PCRE, see
          below).  This is highly experimental and grep  -P  may  warn  of
          unimplemented features.

Это означает, что Вы не должны объявлять массив для своего kewords, можно просто объединить их в единственную строку, разделенную |. Это делает Ваш сценарий намного легче:

#!/usr/bin/env bash

wget --no-clobber -r -E -e robots=off -U mozilla -R gif,jpeg,tif,jpg,pdf,bmp,png,css,js http://www.url.com

KEYWORDS='dolphins|fish|dogs|cats|iguanas'

for file in **; do
    if [[ -r "$file" ]] && [[ -f file ]] ! grep -wqP "$KEYWORDS" "$file"; then
          rm -f "$file" 
    fi
done
2
27.01.2020, 22:00
  • 1
    Это, кажется, пишет в удаленное местоположение вместо каталога, где я выполняю сценарий локально. См.: не Может записать в www.url.com/message/dmca_policy.html' (Permission denied). grep: www.url.com: Is a directory rm: cannot remove www.url.com': каталог –  Guest in need of help 13.01.2014, 21:18
  • 2
    @Guestinneedofhelp OK, таким образом, у Вас есть несколько файлов и папок в Вашем целевом каталоге (необходимо было сказать это в вопросе). Вы хотите к seach через все файлы во всех подкаталогах? –  terdon♦ 13.01.2014, 21:21
  • 3
    у меня еще на самом деле нет их. Функция wget загрузит их, затем команда grep удалит их, если ключевое слово не будет содержаться в файле. –  Guest in need of help 13.01.2014, 21:22
  • 4
    @Guestinneedofhelp umm, хорошо, у Вас будет несколько каталогов затем? Кроме того, Вы уже запустили скрипт однажды и попытались загрузить с псевдоадреса http://www.url.com, это означает Вас теперь hoave названный каталог www.url.com, это - то, что дает Вам ошибки. –  terdon♦ 13.01.2014, 21:25
  • 5
    @Guestinneedofhelp, потому что команда wget один, долгий процесс. Вы не можете остановить его после того, как каждый файл будет загружен, не останавливая сам процесс. –  terdon♦ 13.01.2014, 21:47

Для нахождения любых файлов, которые не содержат определенный шаблон можно использовать:

if ! grep -q $pattern "$file"; then
    # The file does not have a match
    do_stuff_to "$file"
else
    # There is a match
    do_something_else_to "$file"
fi

Так, для использования ключевых слов в качестве примера, после Вашего wget, Вы могли бы использовать:

declare -a KEYWORDS
KEYWORDS=("dolphins" "fish" "dogs" "cats" "iguanas")

for keyword in ${KEYWORDS[@]}; do
    for file in **; do
    if [[ -r "$file" ]] && ! grep -q $keyword "$file"; do
        rm -f "$file"
    fi
done
0
27.01.2020, 22:00
  • 1
    Внимательно изучил то, как я определяю KEYWORDS. Удалите свои запятые. –  DopeGhoti 13.01.2014, 19:39
  • 2
    я сделал незначительное редактирование к своему примеру, попробовали еще раз и если это все еще не работает, добавляет Ваш новый сценарий и его вывод как редактирование к Вашему вопросу, а не выполняет разговор в комментариях. –  DopeGhoti 13.01.2014, 19:52
  • 3
    @Guestinneedofhelp - веб-сайт не разделял форматирование, он просто не загрузил необходимые биты для форматирования - используют --page-requisites опция для этого, больше на этом здесь –  Wilf 13.01.2014, 19:52

Вы надеетесь удалить файл, который не содержит даже единственное ключевое слово? (Другими словами, сохраните файлы, которые содержат по крайней мере одно ключевое слово?) Следующие подарки компактное решение с помощью GNU grep:

rm $(find . -type f -exec grep -LwE 'keyword1|keyword2|keyword3' {} +)

В вышеупомянутом, find . -type f -exec grep -LwE 'keyword1|keyword2|keyword3' {} + перечисляет название всего файла, не содержащего любое ключевое слово. Здесь, три аргумента используются с grep:

  1. w указывает, что все слово должно быть распознано (например, grep -w get file_name указывает, что все слово "добирается", должен быть подобран в файле и не сказать, забыть).
  2. E говорит grep соответствовать для нескольких шаблонов. В этом случае Ваши ключевые слова являются шаблонами.
  3. L печатает имена файлов, не соответствующие любому шаблону. Заключить в кавычки из man страницы:

- L, - уникальный файлами Подавляют нормальный вывод; вместо этого распечатайте название каждого входного файла, из которого обычно не печатался бы никакой вывод. Сканирование остановится на первом соответствии.

Так, однажды find возвращает список имен файлов, можно удалить их использование rm.

Поскольку Вы знаете, rm удалил бы файлы. Так, быть осторожным при выполнении вышеупомянутой команды. Сначала Вы могли бы просто выполниться find управляйте и вручную проверьте, что это работает согласно Вашему требованию.

0
27.01.2020, 22:00
  • 1
    Хороший, но это повредится на именах файлов с пробелами. –  terdon♦ 13.01.2014, 20:33

Теги

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