Я новичок в 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 и заменить две внешние двойные кавычки на '.
Я не уверен в то время как Вы использующий xarg, но могло бы быть много путей к Риму, как обычно. здесь мой подход, например:
#!/bin/bash SRCDIR="$HOME/Pictures/." # should be : /media/et10000 DST="." # should be : /media/newhdd/photos find ${SRCDIR} -type f -exec file {} \; | grep -o -P '^.+: \w+ image' | cut -d':' -f1|while read fname do echo "FILE: ${fname}" filebase=$(dirname $fname); filenew=$(basename "$fname"); echo "filenew: ${filenew}" ## place here all the mkdir, copy and link BUT take care that ## white spaces and other chars needs to be masked - so place your ## variable into this exact way: "${varname}" like ## ln -s "/media/newhdd/photos/year/$(date +%Y)/${fnamebase}" echo "---" done
OP использует двойные кавычки для аргумента sh -c
, который заставляет родительскую оболочку делать замены команды и переменная. Например, "...; echo $fname; ..."
будет заменен родительской оболочкой в "...; echo ; ..."
, потому что родительская оболочка не знает $fname
.
, Если Вы настаиваете на том, чтобы использовать xargs
(вместо while read -r line
), я предлагаю использовать одинарные кавычки для outter-большей-части уровня кавычки, двойные кавычки для следующего уровня кавычки, затем \"
для третьего уровня в случае необходимости.
Я зафиксировал единую команду. И затем я превратил его в сценарий удара. Любые предложения при создании его более читаемый приветствуются все же. :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=\${fname:14};
в fnamenew=\${fname#$1};
.