Feio e frágil, mas deve fazer o trabalho:
find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f -print0 | \
xargs -0 -n 1 \
sh -c 'mkdir -p "$PWD/'dirname $0'"; ln -s "$0" "$PWD/'dirname $0'"'
Inspirado pela resposta do caos , eu criei esta alternativa que também apara diretórios desnecessários :
find /data/DIV5/SASC/e042_ctcl/input/*/Clean_data/*/*/*.fq.gz -type f \
-printf 'mkdir -p "${PWD}/%h"; ln -s "%p" \\n\t"${PWD}/%h"\n' | \
sed 's#/data/DIV5/SASC/e042_ctcl##' | \
sh -
Ele gera os comandos mkdir e ln necessários:
mkdir -p "${PWD}//data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a"; ln -s "/data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a/foobar.fq.gz" \
"${PWD}//data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a"
Em seguida, ele remove os diretórios desnecessários deles com sed , resultando em:
mkdir -p "${PWD}//input/x/Clean_data/0/a"; ln -s "/data/DIV5/SASC/e042_ctcl/input/x/Clean_data/0/a/foobar.fq.gz" \
"${PWD}//input/x/Clean_data/0/a"
O comando ln inicia na mesma linha que mkdir e continua na próxima linha para manter a fonte intacta enquanto corta o destino. Imprimi-los na mesma linha ou em cada linha distinta exigiria um script sed mais complicado.
Explicação da documentação para encontrar , dos parâmetros -printf
:
%p
File's name (not the absolute path name, but the name of the file as it was encountered by find - that is, as a relative path from one of the starting points).
%h
Leading directories of file's name (all but the last element and the slash before it). If the file's name contains no slashes (for example because it was named on the command line and is in the current working directory), then “%h” expands to “.”. This prevents “%h/%f” expanding to “/foo”, which would be surprising and probably not desirable.