Судя по всему, суть вашей задачи/упражнения заключается в SQL-запросах. Я не собираюсь помогать с ними. Но просто подтолкну вас к тому, чтобы вы начали работать с psql cli : )
Следуя командам, которые я часто использую:
# launch psql
psql -U <username> <database>
# list all databases
## here you will find the one they prepared for you
\l
# change database
\c <database_name>
# show tables
\dt
# describe table (show columns)
\d+ <table_name>
чтобы найти другие команды psql, вы можете набрать следующее из psql cli:
\?
Отсюда вы можете начать использовать только SQL для решения задачи. Обратите внимание, что все пункты требуют оператора SELECT.
Есть два основных вопроса в решении этой проблемы. Вам нужно найти все файлы, которые имеют определенные суффиксы имени файла, заданные пользователем, и вам нужно добавить их в архив tar
.
Команда find
имеет параметр -name
, который вы правильно хотите использовать, но он может принимать только один шаблон имени файла. Поскольку пользователь сценария дает нам несколько суффиксов имени файла, нам придется использовать столько опций -name
, сколько имеется суффиксов.
Это означает, что мы должны создать массив из нескольких -name "PATTERN"
опций, где -o
в -между каждым (означает логическое «ИЛИ» между ними ). Затем это будет использоваться с find
для поиска имен файлов с любым из заданных суффиксов имен файлов.
Следующее делает это путем изменения массива$@
:
#!/bin/sh
for suffix do
shift
set -- "$@" -o -name "*.$suffix"
done
shift # remove the very first "-o" from $@
find. -type f \( "$@" \)
Это модифицирует массив $@
, который с самого начала уже содержит суффиксы, заданные в командной строке. В цикле мы удаляем передний элемент из $@
и вставляем наши слова в конец массива.
При вызове этого скрипта как
sh script.sh sh txt c
будет создана команда find
, эквивалентная
find. -type f \( -name '*.sh' -o -name '*.txt' -o -name '*.c' \)
Это находит все соответствующие файлы. Теперь нам осталось только добавить их в архив.
С GNU tar
(, но не с, например. BSD tar
), действие r
позволяет нам обновить или создать архив (BSD tar
только обновляет, но не создает новый архив ).
backup=./PATH/backup.tar
rm -f "$backup"
find. -type f \( "$@" \) -exec tar -r -v -f "$backup" {} +
Это создаст архив ./PATH/backup.tar
с соответствующими файлами.
Причина, по которой я не использую tar -c
, заключается в том, что когда мы вызываем tar
из find
подобным образом, tar
может вызываться более одного раза. Если бы я использовал tar -c
для создания нового нового архива, этот архив усекался бы каждый раз, когда tar
вызывался (, что может быть много раз, если find
находит много тысяч файлов ). Вместо этого, используя tar -r
, мы просто продолжаем обновлять архив.
Таким образом, полный сценарий, возможно, будет выглядеть примерно так:
#!/bin/sh
backup=./PATH/backup.tar
if [ "$#" -eq 0 ]; then
echo 'No filename suffixes given' >&2
exit 1
fi
for suffix do
shift
set -- "$@" -o -name "*.$suffix"
done
shift # remove the very first "-o" from $@
rm -f "$backup"
find. -type f \( "$@" \) -exec tar -r -v -f "$backup" {} +
Обратите внимание, что использование кавычек в приведенном выше скрипте является вполне преднамеренным. Это позволит архивировать файлы с любым разрешенным именем файла, включая имена, содержащие пробелы, символы новой строки и другие необычные символы.
Связанные:
При использовании реализации find
с -print0
вы также можете передать найденные пути в GNU tar
, как в приведенном ниже сценарии:
#!/bin/sh
backup=./PATH/backup.tar
if [ "$#" -eq 0 ]; then
echo 'No filename suffixes given' >&2
exit 1
fi
for suffix do
shift
set -- "$@" -o -name "*.$suffix"
done
shift # remove the very first "-o" from $@
find. -type f \( "$@" \) -print0 | tar -c -v -f "$backup" --null -T -
С помощью -print0
find
будут выводить нулевые -имена путей с разделителями, которые GNU tar
будет читать со своими опциями --null -T -
.
Этот последний скрипт какbash
-специальный скрипт (с использованием массива, names
для -name
опций):
#!/bin/bash
backup=./PATH/backup.tar
if [ "$#" -eq 0 ]; then
echo 'No filename suffixes given' >&2
exit 1
fi
names=( -name "*.$1" )
shift
for suffix do
names+=( -o -name "*.$suffix" )
done
find. -type f \( "${names[@]}" \) -print0 | tar -c -v -f "$backup" --null -T -
С zsh
и GNU tar
илиbsdtar
:
#! /bin/zsh -
set -o extendedglob
output=file.tar.gz
printf '%s\0' **/*.(${(j:|:)~${(b)@}})~$output(D.) |
tar --null -cf - -T - | xz > $output
${(b)@}
:заключает позиционные параметры в кавычки, чтобы их нельзя было принять за шаблоны ${(j:|:)...}
:соединяет полученные слова с|
${~var}
:рассматривает расширение как паттерн подстановки (теперь выглядит как jpg|gif|\*
, если позиционные параметры были jpg
, gif
,*
)**/
:любой уровень подкаталогов pattern~$output
:исключить сам выходной файл из расширения глобуса (D.)
:квалификаторы glob :включают скрытые файлы и выбирают только обычные файлы.