Как я могу исправить мою команду bash, чтобы создать годовую иерархию моих фотографий, используя символические ссылки?
Я новичок в bash и у меня проблемы с использованием переменных в xargs, я думаю.
imanuel@orangepipc:~$ find /media/et10000 -name '*' -exec file {} \; | grep -o -P '^.+: \w+ image' | cut -d':' -f1 | xargs -I {} sh -c "fname="{}"; echo 'filename:'; echo $fname; filebase=$(basename $fname); filenew=${fname:14}; mkdir --parents /media/newhdd/photos$(dirname $fnamenew); cp -dv $fname /media/newhdd/photos$fnamenew; ln -s /media/newhdd/photos/year/$(date +%Y)/$fnamebase /media/newhdd/photos$fnamenew"
Я получаю эту ошибку для каждой фотографии, пока не нажму ^C.
filename:
mkdir: cannot create directory ‘/home/imanuel/photos’: File exists
cp: missing destination file operand after ‘/home/imanuel/photos’
Try 'cp --help' for more information.
ln: failed to create symbolic link ‘/home/imanuel/photos/2016’: File exists
Так что проблема в том, что переменная fname, похоже, не установлена, что бы я ни пытался. Я попытался поместить двойные кавычки вокруг {}, около $fname и заменить две внешние двойные кавычки на '.
3 ответа
Я не уверен, пока вы используете xarg, но в Рим может быть много путей, как обычно. вот мой подход к примеру:
#! / Bin / Баш SRCDIR="$HOME/Pictures/." # должно быть: /media/et10000 DST="" # должно быть: / media / newhdd / photos найти файл ${SRCDIR} типа f -exec {} \; | grep -o -P '^.+: \w+ image' | cut -d':' -f1| при чтении имени делать echo "FILE: ${fname}" filebase=$(dirname $fname); filenew=$(базовое имя "$fname"); echo "filenew: ${filenew}" ## разместите здесь все mkdir, скопируйте и ссылку, но позаботьтесь о том, чтобы ## пробелы и другие символы должны быть замаскированы - поэтому разместите ## Переменная точно так же: "${varname}" вроде ## ln -s "/media/newhdd/photos/year/$(date +%Y)/${fnamebase}" эхо "---" сделанный
ОП использует двойные кавычки для аргумента sh -c
, что заставляет родительскую оболочку выполнять подстановки переменных и команд. Например, "...; echo $fname; ..."
будет заменен родительской оболочкой в "...; echo ; ..."
потому что родительская оболочка не знает $fname
,
Если вы настаиваете на использовании xargs
(вместо while read -r line
), Я предлагаю использовать одинарные кавычки для самого внешнего уровня котировки, двойные кавычки для следующего уровня котировки, затем \"
для третьего уровня, если это необходимо.
Я исправил команду "все в одном". И тогда я превратил его в скрипт bash. Любые предложения о том, как сделать его более читабельным, приветствуются.:D
#!/bin/sh
find "$1" -name '*' -exec file {} \; | grep -o -P '^.+: \w+ image' | cut -d':' -f1 | xargs -I {} sh -c "fname={}; filebase=\$(basename \$fname); fnamenew=\${fname#$1}; mkdir --parents /media/newhdd/photos\$(dirname \$fnamenew); cp -dv \$fname /media/newhdd/photos\$fnamenew; mkdir --parents /media/newhdd/photos/year/\$(date +%Y); ln -fs /media/newhdd/photos\$fnamenew /media/newhdd/photos/year/\$(date +%Y)/\$fnamebase; mkdir --parents /media/newhdd/photos/year/\$(date +%Y/%m-%B); ln -fs /media/newhdd/photos\$fnamenew /media/newhdd/photos/year/\$(date +%Y/%m-%B)/\$fnamebase;"
Основные проблемы со сценарием были следующими:
- Я не избежал знаков доллара, поэтому я заменил каждый
$
с\$
, - Я случайно набрал filenew вместо fnamenew, а функция подстроки не была доступна в Dash (Debian Almquist Shell), поэтому я изменил
filenew=\${fname:14};
вfnamenew=\${fname#$1};
, - Первоначально я поставил двойные кавычки вокруг {}, но это была опечатка.:)