Вы можете поместить в каталог /etc/profile.d/ что-то вроде следующего в виде скрипта:
#!/bin/bash
if [ $SHLVL = 1 ]; then
echo -n "Enter proxy password:"
read -sr mypass
export http_proxy="http://$USER:$mypass@proxy.example.com:6080"
export https_proxy=$http_proxy
echo
fi
if [ $SHLVL = 1 ]
предотвратит запуск сценария при создании подоболочек, например, при запуске сценария для ведения журнала.
read -s
предотвратит эхо ввода при вводе пароля.
$USER
— это переменная среды, которая является текущим именем пользователя.
Окончательный echo
просто печатает новую строку, чтобы получить следующее приглашение на следующей строке.
Выполняется find
один раз для каждого имени файла и предполагается, что ни одно имя файла не содержит встроенных символов новой строки:
#!/bin/sh
mkdir -p destination_folder || exit 1
while IFS= read -r name; do
find. -path./destination_folder -prune -o \
-type f -name "$name" -exec cp {} destination_folder \;
done <spreadsheet.txt
Сначала создается целевой каталог в текущем каталоге (и завершается, если это не удается ). Затем он считывает входной файл, строка за строкой, и вызывает find
, чтобы найти любой обычный файл с таким именем. Каталог назначения явно избегается с помощью find
с использованием -prune
всякий раз, когда мы сталкиваемся с ним в нашем поиске.
Всякий раз, когда обнаруживается файл с правильным именем, он копируется в каталог назначения. Если несколько файлов имеют одинаковое имя, копия в destination_folder
будет перезаписана.
Если текущий каталог огромен, или если список имен файлов длинный (, но не много тысяч строк ), то это будет медленная операция. Поэтому мы можем сделать одиночный вызов find
. Следующий код предполагает, что он выполняется, например. bash
поскольку он использует массивы:
#!/bin/bash
mkdir -p destination_folder || exit 1
names=()
while IFS= read -r name; do
names+=( -o -name "$name" )
done <spreadsheet.txt
find. -path./destination_folder -prune -o \
\( "${names[@]:1}" \) -type f -exec cp -t destination_folder {} +
Здесь я также решил использоватьcp -t
(расширение GNU cp
), чтобы иметь возможность вызывать cp
как можно меньше раз, а не один раз для каждого найденного файла.
Приведенный выше код строит массив names
, который в конечном итоге будет иметь правильный формат для использования с find
. Команда, которая фактически выполняется в конце приведенного выше кода, с учетом примера в вашем вопросе, будет
find. -path./destination_folder -prune -o '(' -name AB.txt -o -name CD.txt -o -name EF.txt ')' -type f -exec cp -t destination_folder '{}' +
Чтобы избежать конфликта имен файлов в целевом каталоге, если вы используете GNU cp
(, например. в системе Linux ),использовать cp
с его опцией -b
или --backup
.
В системах, отличных от -Linux, GNU cp
часто может быть доступен как gcp
после установки GNU coreutils через диспетчер пакетов.
Тот же последний скрипт, но для/bin/sh
(нет массивов):
#!/bin/sh
mkdir -p destination_folder || exit 1
set --
while IFS= read -r name; do
set -- -o -name "$name" "$@"
done <spreadsheet.txt
shift
find. -path./destination_folder -prune -o \
\( "$@" \) -type f -exec cp -t destination_folder {} +
Простой цикл for:
for filename in $(cat spreadsheet.txt)
do
find. -name "$filename" -exec cp {} /destination/folder \;
done