Как я могу исправить мою команду 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};,
  • Первоначально я поставил двойные кавычки вокруг {}, но это была опечатка.:)
Другие вопросы по тегам