2016-10-06 2 views
4

Прежде всего, я новичок с bash-скриптами, поэтому простите меня, если я делаю легкие ошибки.find - grep занимает слишком много времени

Вот моя проблема. Мне нужно было скачать сайт моей компании. Я выполняю это с помощью wget без каких-либо проблем, но поскольку некоторые файлы имеют символ ?, а окна не любят имена файлов с ?, мне пришлось создать скрипт, который переименовывает файлы, а также обновляет исходный код всех файлов, вызывающих файл переименования.

Для этого я использую следующий код:

find . -type f -name '*\?*' | while read -r file ; do 
SUBSTRING=$(echo $file | rev | cut -d/ -f1 | rev) 
NEWSTRING=$(echo $SUBSTRING | sed 's/?/-/g') 
mv "$file" "${file//\?/-}" 
grep -rl "$SUBSTRING" * | xargs sed -i '' "s/$SUBSTRING/$NEWSTRING/g" 
done 

Это с 2 проблемы.

  1. Это длится слишком долго, я ждал более 5 часов и все еще идет.
  2. Похоже, что это добавление в исходный код, потому что, когда я останавливаю скрипт и ищу изменения, URL повторяется как 4 раза (или больше).

Спасибо всем за ваши комментарии, я постараюсь шаг 2 раздельных и посмотреть, также, как FYI, есть 3291 файлов, которые были загружены с Wget, все еще думая, что с помощью Баша скриптового предпочитают по сравнению с другими инструментами для это?

+0

Вы уверены, что это на самом деле работает, не просто ожидая ввода? – Biffen

+0

Обратите внимание, что более вероятно, что '?' символы в некоторых ваших URL-адресах вводят строку запроса. Это указывает на то, что основной ресурс, вероятно, является динамическим и может возвращать разные материалы в разное время. –

+0

Вы можете выполнить инкрементную отладку, сначала используя эхо-файл, найденный в команде find, затем добавьте другие операции. – Inian

ответ

1

Хорошо, вот идея (непроверенная):

  • в первом цикле, просто перемещать файлы и создавать глобальный патч в файл замена
  • как только это будет сделано, просто сканировать все файлы и применять sed со всеми шаблонами одновременно, что позволяет сэкономить много операций чтения/записи, которые могут стать причиной проблемы с производительностью.
  • Я бы не стал помещать текущий скрипт в текущий каталог, иначе он будет обработан sed, поэтому я полагаю, что все файлы, которые нужно обработать, находятся не в текущем каталоге, а в data каталог

код:

sedfile=/tmp/tmp.sed 
data=data 
rm -f $sedfile 
# locate ourselves in the subdir to preserve the naming logic 
cd $data 

# rename the files and compose the big sedfile 

find . -type f -name '*\?*' | while read -r file ; do 
SUBSTRING=$(echo $file | rev | cut -d/ -f1 | rev) 
NEWSTRING=$(echo $SUBSTRING | sed 's/?/-/g') 
mv "$file" "${file//\?/-}" 
echo "s/$SUBSTRING/$NEWSTRING/g" >> $sedfile 
done 

# now apply the big sedfile once on all the files:  
# if you need to go recursive: 
find . -type f | xargs sed -i -f $sedfile 
# if you don't: 
sed -i -f $sedfile * 
+0

спасибо за это, это исправить время для выделения. –

+0

Я рад, что это так. Я не смог полностью протестировать его. Отлично! –

2

Кажется странным, что файл имел бы? в этом. URL веб-сайта имеют? для указания прохождения параметров. wget с веб-сайта также не гарантирует, что вы получаете сайт, особенно если выполняется выполнение на стороне сервера, например php-файлы. Итак, я подозреваю, что, поскольку wget выполняет свою рекурсивность, он находит параметры передачи url и тем самым создает их для вас.

Чтобы получить сайт, вы должны иметь прямой доступ к файлам.

Если бы я был вами, я бы начал использовать и не использовать wget.

У вас могут также возникнуть проблемы с файлами или каталогами с пробелами в их имени.

Вместо этой строки с xargs вы уже делаете по одному файлу за раз, но grepping для всех рекурсивно. Просто сделайте sed в новом файле.

+0

Привет, спасибо за ответ, но прямой доступ к файлам не является опцией, и да, это веб-сайт в jsp, который имеет выполнение на стороне сервера, поэтому создается файл с параметрами. Проблема с использованием sed в файле, который у меня уже есть, заключается в том, что мне нужно обновить все файлы с сайта, ссылающиеся на тот, который я переименовываю, поэтому у меня есть рекурсивный grep, начиная с корня еще раз. –

+0

Несмотря на то, что вы представляете разумные советы, он не затрагивает фактически заданный вопрос (ы), который связан с манипулированием именами и содержимым коллекции файлов, уже присутствующих на машине (ранее загруженных). –

0

Вместо использования grep, вы можете использовать команду find команду или ls список файлов, а затем работать непосредственно на них.

Например, вы могли бы сделать:

ls -1 /path/to/files/* | xargs sed -i '' "s/$SUBSTRING/$NEWSTRING/g" 

Вот где у меня появилась идея основана на другой вопрос, где grep слишком долго:

Linux - How to find files changed in last 12 hours without find command

Смежные вопросы