Como eu corrijo meu comando bash para fazer uma hierarquia baseada em anos de minhas fotos usando links simbólicos?

1

Eu sou novo no bash e estou tendo problemas com o uso de variáveis no xargs, eu acho.

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"

Eu recebo esse erro para cada foto até que eu pressione ^ 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

Portanto, o problema é que a variável fname não parece definida, seja qual for a minha tentativa. Eu tentei colocar aspas duplas em torno de {}, em torno de $ fname e substituir as duas aspas duplas externas por '.

    
por Imanuel Habekotte 11.08.2016 / 14:35

3 respostas

1

Não sei ao usar o xarg, mas pode haver muitas maneiras para Roma, como de costume. aqui minha abordagem por exemplo:

#!/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
    
por 0x0C4 11.08.2016 / 16:46
0

O OP usa aspas duplas para o argumento para sh -c , o que faz com que o shell pai faça substituições de comando e variável. Por exemplo, "...; echo $fname; ..." será substituído pelo shell pai em "...; echo ; ..." porque o shell pai não conhece $fname .

Se você insistir em usar xargs (em vez de while read -r line ), sugiro usar aspas simples para o nível de cotação mais longo, aspas duplas para o próximo nível de cotação e \" para o terceiro nível, se necessário .

    
por Matei David 11.08.2016 / 18:39
0

Eu consertei o comando all-in-one. E então eu transformei em script bash. Todas as sugestões para torná-lo mais legível são bem-vindas. : D

#!/bin/sh
find "" -name '*' -exec file {} \; | grep -o -P '^.+: \w+ image' | cut -d':' -f1 | xargs -I {} sh -c "fname={}; filebase=$(basename $fname); fnamenew=${fname#}; 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;"

Os principais problemas com o script foram estes:

  • Eu não escapei dos cifrões, então substituí todos os $ por $ .
  • Eu acidentalmente digitei filenew em vez de fnamenew e a funcionalidade substring não estava disponível no Dash (Debian Almquist Shell), então mudei filenew=${fname:14}; para fnamenew=${fname#}; .
  • Originalmente, coloquei aspas duplas em {}, mas esse foi um erro de digitação. :)
por Imanuel Habekotte 11.08.2016 / 18:56