Crie links simbólicos para vários livros coletados a partir do comando 'find'

0

Gostaria de criar links simbólicos para vários livros pesquisados a partir do comando find .

Primeiramente, eu coleciono todos os livros de JS

find ~ -type f -iregex  '.*javascript.*\.pdf' > js_books.md 2>/dev/null

Devolve 35 livros

../Coding/Books/HTML_Collections/Freeman E.T., Robson E. - Head First HTML5. Programming Building Web Apps with JavaScript - 2011.pdf
../Coding/Books/HTML_Collections/Learning Web Design - A Beginner's Guide to HTML, CSS, JavaScript, and Web Graphics - Jennifer Niederst Robbins - 4th Edition - August 2012.pdf
..

Além disso, copie-os para o diretório js_books

mkdir js_books
find ~ -type f -iregex  '.*javascript.*\.pdf' -print0 -exec cp '{}' js_books

Funciona, no entanto, várias cópias consomem muito espaço em disco.
Então, eu apago os livros e tento criar um link simbólico.

find ~ -type f -iregex  '.*javascript.*\.pdf' -print0 -exec ln -s '{}' js_books/'{}' \;

Não retorna nada no diretório js_books.

Como resolver tal problema?

    
por JawSaw 29.03.2018 / 16:24

3 respostas

2

Sua expressão find é simples o suficiente para ser replicada com globbing de shell bash:

shopt -s globstar nocaseglob
for book in $HOME/Coding/**/*javascript*.pdf
do
  ln -s "$book" "js_books/$(basename "$book")" 
done

Primeiro, dizemos ao bash para habilitar globbing de nomes de maiúsculas e minúsculas e poder recopiar subdiretórios por meio de ** , então fazemos um loop sobre todos os nomes de arquivos que correspondem ao padrão "(qualquer coisa) javascript (qualquer coisa) pdf". Para cada um desses nomes de arquivos, criamos um link simbólico em js_books.

Você omitiu o início de cada nome de arquivo, por isso eu apenas observarei que você desejará fornecer o caminho completo no for loop para que o comando ln crie links simbólicos válidos (ou use a quantidade adequada de ../ prefixos no destino do symlink). Eu substituí seu find ~ por $HOME/Coding , apenas no caso de você estar usando um diretório inicial diferente.

    
por 29.03.2018 / 20:38
0

O destino js_books/'{}' deve ser apenas js_books . Se for um diretório, o ln usa apenas o mesmo nome do arquivo original.

O problema aqui é que {} adiciona nomes de diretórios superiores, o que compromete a função.

    
por 29.03.2018 / 16:38
0

Uma maneira seria fazer o seguinte:

find ~ -type f -iregex  '.*javascript.*\.pdf' -printf %f"*"%h | awk -F* '{ system("ln -s "$2"/"$1" "$2"/js_books/"$1) }'

Execute o comando find e imprima o nome do arquivo seguido por um asterisco e, em seguida, pelo caminho do diretório. Execute isto através do awk, separando o nome do arquivo e o diretório e construindo o comando ln para executar com a função do sistema do awk.

Desconfie que isso esteja aberto para comando injetar e também use print para imprimir o comando para a tela antes de executar o comando final com o sistema.

    
por 29.03.2018 / 17:00

Tags