1

Если я скопирую / вставлю это в командной строке, я могу загрузить ВСЕ архивные файлы GitHub в течение 24 часов 1 января 2015 года:

wget http://data.gharchive.org/2015-01-01-{0..23}.json.gz

Я хочу быть в состоянии сделать это в течение нескольких дней, используя скрипт. Например, в моем файле .sh:

#!/bin/bash

while read line
do
    wget $line
  done < download_github_files.txt

И в download_github_files.txt меня есть:

http://data.gharchive.org/2015-01-01-{0..23}.json.gz
http://data.gharchive.org/2015-01-02-{0..23}.json.gz
http://data.gharchive.org/2015-01-03-{0..23}.json.gz

К сожалению, когда я запускаю файл .sh, я получаю три распечатки:

--2019-02-27 19:00:28--  http://data.gharchive.org/2015-01-01-'%7B'0..23'%7D'.json.gz
Resolving data.gharchive.org (data.gharchive.org)... 
Connecting to data.gharchive.org (data.gharchive.org)...
connected.
HTTP request sent, awaiting response... 404 Not Found
2019-02-27 19:00:28 ERROR 404: Not Found.

Проблема явно с { . Экранирование этого символа не помогает, потому что он должен быть итератором из того, что я могу сказать.

Как я могу скачать эти файлы с помощью wget?

РЕДАКТИРОВАТЬ:

Хм. У меня та же проблема, я пытаюсь использовать первое опубликованное решение:

Файл .sh (ясно, что я собираюсь делать все месяцы года, но я ограничился февралем для простоты визуализации):

#!/bin/bash

for i in {01..12}; do
    if [ ${i} = 02 ]; then
        for j in {01..28}; do
            for k in {0..23}; do
                wget http://data.gharchive.org/2011-${i}-${j}-${k}.json.gz
            done
        done
    fi
done

Та же проблема. Например, я получаю:

--2019-02-27 20:50:05--  http://data.gharchive.org/2011-02-01-5.json.gz
Resolving data.gharchive.org (data.gharchive.org)... 
Connecting to data.gharchive.org (data.gharchive.org)...
HTTP request sent, awaiting response... 404 Not Found
2019-02-27 20:50:05 ERROR 404: Not Found.

Но если я запускаю команду

wget http://data.gharchive.org/2011-02-01-5.json.gz

тогда у меня нет проблем. Я могу загрузить файл вручную, но не могу сделать это в скрипте bash. Есть другие идеи?

2 ответа2

0

Просто поместите wget в цикл for итератора, например так:

#!/bin/bash

for i in {1..23}; do
  wget http://data.gharchive.org/2015-01-01-${i}.json.gz;
done
0

Расширение фигурных скобок происходит перед расширением переменной, поэтому фигурные скобки, назначенные $line , не раскрываются.

Это должно работать:

eval wget $line

где eval снова оценивает строку. На данный момент $line уже раскрыт, и оболочка оценивает строку, которая выглядит как ваша первая команда:

wget http://data.gharchive.org/2015-01-01-{0..23}.json.gz

Но будьте осторожны! Запись как

foo; rm -rf /some/precious/directory

в файле download_github_files.txt приведет к следующей строке оцениваются:

wget foo; rm -rf /some/precious/directory

"Оцененный" означает ; выполняет отдельные команды (хотя без eval этого ; приход из $line будет просто частью foo; аргумент передается в wget).

См. Почему в Bash следует избегать eval , и что мне вместо этого использовать? Я сомневаюсь, что эта ссылка содержит все, что вы могли бы легко использовать вместо eval в данном конкретном случае, но она проливает свет на некоторые общие вопросы. Используйте eval только если файл содержит строки под вашим полным контролем, и вы уверены, что они будут оценены без сюрпризов.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .