#bash #csv #pdf #curl #wget
Вопрос:
Я пытаюсь создать скрипт bash, который считывает CSV-файл с двумя столбцами:
first column = name
second column = URL
и попробуйте загрузить PDF-файл с URL-адреса во втором столбце со случайным именем с буквами и цифрами .pdf и измените имя, используя первый столбец.
Имя PDF может быть дублированным, поэтому, если оно дублируется, я хочу добавить такие цифры, как:
Example $5000.pdf
Example $5000.1.pdf
Example $5000.2.pdf
Потому что, если я попытаюсь загрузить wget, и curl не будет автоматически увеличиваться с опцией вывода.
Я перепробовал много вещей, но мои ограничения отнимают слишком много времени.
Я создал счетчик, который добавляет номер строки в конец, но если я получу файл PDF большего размера, то будут ненужные числа с автоматическим приращением. (код ниже)
Должен быть лучший метод, но мой недостаток знаний отнимает слишком много времени. Так что любая помощь в этом будет очень признательна, я новичок в сценариях bash.
Заранее спасибо за любую помощь!
Пример CSV:
Example $5000,HTTP://example.com/djdiede.pdf
Example $5000,HTTP://example.com/djdi42322ede.pdf
Example 0 $1000,HTTP://example.com/djd4234iede.pdf
Example P $1000,HTTP://example.com/dj43566diede.pdf
Код до сих пор:
#!/bin/bash -e
COUNTER=1
while IFS=, read -r field1 field2
do
COUNTER=$[$COUNTER 1]
if [ "$field1" == "" ]
then
echo "Line $COUNTER field1 is empty or no value set"
elif [ "$field2" == "" ]
then
echo "Line $COUNTER field2 is empty or no value set"
else
pdf_file=$(echo $field1 | tr '/' ' ')
echo "================================================"
echo "Downloading $COUNTER $pdf_file..."
echo "================================================"
pdf_file_test="$pdf_file.pdf"
if [ -e "$pdf_file_test" ]; then
echo -e "33[32m ^^^ File already exists!!! Adding line number at the end of the file: $pdf_file.$COUNTER.pdf 33[0m" >amp;2
wget -q -nc -O "$pdf_file."$COUNTER.pdf $field2
else
wget -q -nc -O "$pdf_file".pdf $field2
fi
fi
done < test.csv
Ответ №1:
Это должно помочь. Я старался держаться поближе к вашему собственному стилю кодирования:
#!/bin/bash -e
LINECOUNTER=0
while IFS=, read -r field1 field2
do
LINECOUNTER=$[$LINECOUNTER 1]
if [ "$field1" == "" ]
then
echo "Line $LINECOUNTER: field1 is empty or no value set"
elif [ "$field2" == "" ]
then
echo "Line $LINECOUNTER: field2 is empty or no value set"
else
pdf_file=$(echo "$field1" | tr '/' ' ')
echo "================================================"
echo "Downloading $LINECOUNTER: $pdf_file..."
echo "================================================"
pdf_file_saveas="$pdf_file.pdf"
FILECOUNTER=0
while [ -e "$pdf_file_saveas" ]
do
FILECOUNTER=$[$FILECOUNTER 1]
pdf_file_saveas="$pdf_file.$FILECOUNTER.pdf"
done
if [ $FILECOUNTER -gt 0 ]
then
echo -e "33[32m ^^^ File already exists!!! Adding number at the end of the file: $pdf_file_saveas 33[0m" >amp;2
fi
wget -q -nc -O "$pdf_file_saveas" "$field2"
fi
done < test.csv
Вот что я сделал:
- используйте два счетчика: один для строк, один для файлов
- если файл уже существует, используйте счетчик файлов цикл, чтобы найти следующий «пустой слот» (т. е. файл с именем
<filename>.<counter-value>.pdf
, которого не существует). - исправлены неправильные номера строк (счетчик строк должен начинаться с 0 вместо 1)
- добавлены двойные кавычки, где это необходимо/желательно
Если вы хотите еще больше улучшить свой сценарий, вот несколько предложений:
- вместо большой
if ... elif ... else
конструкции вы можете использоватьif
continue
, напримерif [ "$field1" == "" ]; then continue; fi
, или даже[ "$field1" == "" ] amp;amp; continue
- вместо того, чтобы заканчивать с error (
#!/bin/bash -e
), вы можете добавить обнаружение и обработку ошибок послеwget
вызова, напримерif [ $? -ne 0 ]; then echo "failed to download ..."; fi
Комментарии:
1. Классно! Спасибо вам за все объяснения, сработали отлично, и я буду работать над улучшениями, спасибо вам огромное!
2. @AndersonCursino: добро пожаловать 🙂 Удачи!