O reverso da 'árvore' - reconstrói a estrutura de arquivos e diretórios do conteúdo do arquivo de texto?

3

Todos nós sabemos que podemos usar tree para obter uma "visualização" de texto bem formatada da estrutura de um diretório; diga:

$ tree -spugD /usr/include/boost/accumulators/numeric/
/usr/include/boost/accumulators/numeric/
├── [drwxr-xr-x root     root            4096 Dec 19  2011]  detail
│   ├── [-rw-r--r-- root     root            2681 Oct 21  2010]  function1.hpp
│   ├── [-rw-r--r-- root     root             406 Oct 21  2010]  function2.hpp
│   ├── [-rw-r--r-- root     root             409 Oct 21  2010]  function3.hpp
│   ├── [-rw-r--r-- root     root             409 Oct 21  2010]  function4.hpp
│   ├── [-rw-r--r-- root     root            6725 Oct 21  2010]  function_n.hpp
│   └── [-rw-r--r-- root     root             530 Oct 21  2010]  pod_singleton.hpp
├── [drwxr-xr-x root     root            4096 Dec 19  2011]  functional
│   ├── [-rw-r--r-- root     root            2316 Oct 21  2010]  complex.hpp
│   ├── [-rw-r--r-- root     root           16627 Oct 21  2010]  valarray.hpp
│   └── [-rw-r--r-- root     root           12219 Oct 21  2010]  vector.hpp
├── [-rw-r--r-- root     root            9473 Oct 21  2010]  functional_fwd.hpp
└── [-rw-r--r-- root     root           21312 Oct 21  2010]  functional.hpp

2 directories, 11 files

O que eu gostaria, é o contrário disso - dado um arquivo de texto com o conteúdo acima, salvo em dirstruct.txt , eu poderia escrever algo assim (pseudo):

$ reverse-tree dirstruct.txt -o /media/destpath

... e assim, o diretório /media/destpath seria criado se não existisse, e por dentro eu obteria detail subpasta com arquivos function1.hpp , etc; conforme a árvore acima.

Claro, sempre posso fazer uma cópia cp -a e obter o mesmo; a idéia aqui seria que eu poderia alterar nomes de arquivos, nomes de diretórios, tamanhos, permissões e registros de data e hora no arquivo de texto - e ter isso reconstruído na estrutura de saída. Para arquivos, primeiro pensei que ficaria feliz com eles sendo apenas touch ed (isto é, 0 bytes de tamanho) - mas provavelmente é melhor que o tamanho também seja reconstruído - preenchendo 0x00 ou bytes aleatórios, até o tamanho solicitado.

O uso principal disso seria, na verdade, postar questões :) - algumas delas dependem de uma estrutura de diretórios, digamos, de um programa que eu instalei; mas o programa em si é irrelevante para a questão; então, em vez de direcionar os respondentes que podem ter o programa instalado, eu poderia simplesmente fazer uma pergunta em relação a uma árvore de diretórios "anônima", que eles próprios poderiam reconstruir rapidamente em suas máquinas, simplesmente colando a descrição do texto da árvore no post .

Então - existe uma maneira simples de conseguir isso?

    
por sdaau 04.07.2014 / 13:23

2 respostas

1

Não existe essa ferramenta que eu já vi. Você poderia escrever um script em uma variedade de linguagens de script, incluindo Bash, para analisar a saída de tree e reconstruir um diretório correspondente no disco correspondente. Examinar o arquivo de texto exigiria um% while ou for loop e fazendo uso de mkdir ou mkdiir -p para criar um diretório ou uma estrutura de diretório aninhada, seguido pelo uso do comando touch para criar vazio versões dos arquivos no arquivo de texto também.

Você pode até replicar os carimbos de data e hora associados, pois mkdir e touch oferecem isso também como argumento, caso você deseje obter a estrutura totalmente replicada.

    
por 04.07.2014 / 14:31
0

Ok, como eu precisava disso novamente, eu montei um script Perl que faz isso; acabou por ser um pouco complicado, então eu lancei aqui:

O que ele faz é que ele analisa a saída de tree - mas, ao contrário do exemplo do OP, ele também precisa da opção --dirsfirst . Para evitar lembrar de tudo isso, o revrs-tree.pl pode ser usado primeiro assim:

perl revrs-tree.pl --getdir /usr/include/boost/accumulators/ > test.tree

... que simplesmente chamará tree com as opções corretas, que saem para stdout - nós capturamos isso em um arquivo test.tree .

Em seguida, chamamos o mesmo script no test.tree content; mas o truque é que a saída não são os próprios diretórios / arquivos, mas as linhas em um script bash são impressas no stdout. A chamada é assim:

perl revrs-tree.pl --zerofill test.tree > test-tree.sh
# alternatively, can receive tree text from stdin:
cat test.tree | perl revrs-tree.pl --zerofill > test-tree.sh

... e test-tree.sh contém coisas como:

RTD="/usr/include/boost/accumulators";
read -p "WARNING! will output in '$RTD' directory!
Press [Enter] key to start output...";
if [ ! -d "$RTD" ] ; then mkdir "$RTD" ; fi ;

TDIR="$RTD/framework";
mkdir "$TDIR"; sudo chown root:root "$TDIR"; sudo chmod 755 "$TDIR"; sudo touch -d 'Jul 16 2014 9:43:00' "$TDIR";

TDIR="$RTD/framework/accumulators";
mkdir "$TDIR"; sudo chown root:root "$TDIR"; sudo chmod 755 "$TDIR"; sudo touch -d 'Jul 16 2014 9:43:00' "$TDIR";

TFIL="$RTD/framework/accumulators/droppable_accumulator.hpp";
cat /dev/zero | head --bytes 9740 >  "$TFIL";
touch -d 'Oct 21 2010 0:00:00' "$TFIL"; sudo chown root:root "$TFIL"; sudo chmod 644 "$TFIL";
...

O truque aqui é:

  • Lembre-se de alterar o RTD antes de executar o script - eu não o fiz uma vez e consegui sobrescrever /usr/include/boost/accumulators com arquivos com preenchimento zero! (que então exigiu sudo apt-get remove --purge libboost1.42-dev && sudo apt-get install libboost1.42-dev para mim) !!! (é por isso que o script aguardará no início pela entrada do usuário) ... Digamos que aqui você alterou para /tmp/newtarget .
  • tree não fornece registros de data e hora completos - portanto, os horários geralmente são definidos como 0
  • tree também trunca uids / gids para 7 ou 8 caracteres - por isso, se você tiver mais do que isso, inspecione o script .sh e substitua onde for apropriado.

Então, porque aconteceu que o exemplo do OP foi o diretório root possuído, o script .sh contém sudo nos locais apropriados, então você também pode chamá-lo como superusuário:

sudo bash test-tree.sh

Após muitas impressões de set -x , o script deve ser concluído. então você pode verificar se a estrutura da árvore de diretórios / arquivos foi reconstruída corretamente com, por exemplo, diff - ou meld :

meld <(tree -spugD /tmp/newtarget/) <(tree -spugD /usr/include/boost/accumulators/)

Isso não me dá nenhuma diferença em tree output (para este exemplo), além do diretório raiz.

Bem, espero que isso ajude alguém ...

    
por 16.07.2014 / 10:23