Criando 50 diretórios com 50 arquivos dentro

6

Estou tentando criar 50 diretórios (dir-01..dir-50). E eu quero criar 50 arquivos (01.txt..50.txt) dentro de cada um dos 50 diretórios.

For example:
    dir-01/01.txt..50.txt
    dir-02/02.txt..50.txt
    etc...

Eu posso criar os diretórios, mas estou tendo problemas para criar os arquivos dentro deles. Eu também estou tentando comprimir tudo isso depois em um arquivo tar.

Aqui é onde eu estou:

for i in {1..50};
   do mkdir dir-$i;
done;
for j in {1..50};
   do touch $j.txt.dir-*;
done;
tar -cf final.tar dir-{1..50}

Eu sei que o segundo loop está errado, mas não tenho certeza de como proceder. Qualquer conselho é apreciado.

Isso parece funcionar, mas não tenho certeza se está correto na sintaxe ou no formato:

for i in {1..50}; do
  mkdir "dir-$i";
  for j in {1..50}; do
      touch "./dir-$i/$j.txt";
    done;
done;

tar -cf final.tar dir-{1..50}
    
por Babeeshka 29.09.2017 / 03:13

6 respostas

25

Com zsh ou bash ou yash -o braceexpand :

$ mkdir dir-{01..50}
$ touch dir-{01..50}/file{01..50}.txt
$ ls dir-45
file01.txt file09.txt file17.txt file25.txt file33.txt file41.txt file49.txt
file02.txt file10.txt file18.txt file26.txt file34.txt file42.txt file50.txt
file03.txt file11.txt file19.txt file27.txt file35.txt file43.txt
file04.txt file12.txt file20.txt file28.txt file36.txt file44.txt
file05.txt file13.txt file21.txt file29.txt file37.txt file45.txt
file06.txt file14.txt file22.txt file30.txt file38.txt file46.txt
file07.txt file15.txt file23.txt file31.txt file39.txt file47.txt
file08.txt file16.txt file24.txt file32.txt file40.txt file48.txt

$ tar -cf archive.tar dir-{01..50}

com ksh93 :

$ mkdir dir-{01..50%02d}
$ touch dir-{01..50%02d}/file{01..50%02d}.txt
$ tar -cf archive.tar dir-{01..50%02d}

A expansão ksh93 brace usa uma string de formato printf() que pode ser usada para criar os números com zeros.

Com um POSIX sh :

i=0    
while [ "$(( i += 1 ))" -le 50 ]; do
    zi=$( printf '%02d' "$i" )
    mkdir "dir-$zi"

    j=0
    while [ "$(( j += 1 ))" -le 50 ]; do
        zj=$( printf '%02d' "$j" )
        touch "dir-$zi/file$zj.txt"
    done
done

tar -cf archive.tar dir-*  # assuming only the folders we just created exists

Uma alternativa para criar seu arquivo tar sem criar muitos arquivos, em bash :

mkdir dir-01
touch dir-01/file{01..50}.txt
tar -cf archive.tar dir-01

for i in {02..50}; do
    mv "dir-$(( i - 1 ))" "dir-$i"
    tar -uf archive.tar "dir-$i"
done

Isto apenas cria um dos diretórios e adiciona-o ao arquivo. Como todos os arquivos em todos os 50 diretórios são idênticos em nome e conteúdo, ele renomeia o diretório e o acrescenta ao arquivo em iterações sucessivas para adicionar os outros 49 diretórios.

    
por 29.09.2017 / 08:21
6

POSIXly e para evitar problemas quando essa lista de 50 x 50 caminho do arquivo exceder potencialmente o limite do tamanho de args + env:

awk 'BEGIN{for (i = 1; i <= 50; i++) printf "dir-%02d\n", i}' |
  xargs mkdir &&

  awk 'BEGIN{for (i = 1; i <= 50; i++)
              for (j = 1; j <= 50; j++)
                printf "dir-%02d/file-%02d.txt\n", i, j}' |
    xargs touch

Com zsh (de onde {01..50} vem), você pode contornar a lista de argumentos por muito tempo com zargs :

autoload zargs
mkdir dir-{01..50}
zargs dir-{01..50}/file-{01..50}.txt -- touch

Você também pode criar dir{02..50} links simbólicos para dir-01 e usar a opção h tar :

mkdir dir-01
touch dir-01/file-{01..05}
for d in dir-{02..05}; do ln -s dir-01 "$f"; done
tar zchf file.tar.gz dir-{01..50}
    
por 29.09.2017 / 10:50
5

Para cada diretório, crie 50 arquivos:

for i in {1..50}; do
    mkdir dir$i
    touch dir$i/file{1..50}
done

E para fazer a contagem, ls -l dir*/* | nl = 2500

    
por 29.09.2017 / 04:09
4

A resposta foi mais fácil do que você pensou:

for i in {1..50}; do
  mkdir "dir-$i"
  touch "./dir-$i/dir-$i.txt"
done

tar -cf final.tar dir-{1..50}
    
por 29.09.2017 / 03:34
4

Eu acredito que isso funcionaria como você queria.

for i in {1..50}; do mkdir $i.dir; cd $i.dir ; touch {1..50}.txt; cd ..; done; tar -cf dirs.tar *.dir; find . -type f | wc -l

Explicação:

  1. Aqui no primeiro loop, o bash criará um diretório com o nome 1.dir [ mkdir $i.dir ].

  2. Em seguida, ele será digitado no diretório 1.dir [ cd $i.dir ]

  3. Em seguida, ele criará 50 arquivos. Para criar 50 arquivos, usei a funcionalidade brace expansion do bash (como você usou para) com touch [ touch {1..50}.txt ].

  4. Em seguida, ele retornará seu diretório atual [ cd .. ] e iniciará o trabalho de loop.

  5. Após terminar o trabalho em loop, tar dos diretórios com .dir serão exibidos no final do nome. [ tar -cf dirs.tar *.dir ].

  6. Então usei o comando find [ find -type f | wc -l ] para mostrar quantos arquivos foram criados. Você verá 2551 arquivos ("50 * 50 = 2550 +1" - o extra 1 é o seu arquivo .tar).

Você pode usar isso diretamente na linha de comando ou também pode usá-lo como um script.

    
por 29.09.2017 / 04:38
1

Você não especificou o ambiente de trabalho e, embora pareça ser bash / GNU, achei que a solução a seguir era suficientemente interessante para ser lançada no caldeirão. Ele usa a versão BSD de tar(1) (geralmente disponível como bsdtar em plataformas não-BSD) e usa seu recurso @<mtree> para fornecer a especificação do conteúdo do arquivo no formato mtree .

awk -v tmpdir='mktemp -d' -v tmpfile='mktemp' -v uid='id -u' -v gid='id -g' 'BEGIN {print "#mtree"; print "/set uid=" uid " gid=" gid " mode=755";  for(d=1;d<=50;d++) {printf "dir-%02d type=dir content=%s\n", d, tmpdir; for(f=1;f<=50;f++) printf "%02d.txt type=file content=%s\n", f, tmpfile; print "..";}}' | tar cf final.tar @-

Dividir para facilitar a leitura:

awk -v tmpdir='mktemp -d' -v tmpfile='mktemp' -v uid='id -u' -v gid='id -g' \
    'BEGIN {print "#mtree"; print "/set uid=" uid " gid=" gid " mode=755"; \
    for(d=1;d<=50;d++) {printf "dir-%02d type=dir content=%s\n", d, tmpdir; \
        for(f=1;f<=50;f++) printf "%02d.txt type=file content=%s\n", f, tmpfile; \
        print "..";}}' \
| tar cf final.tar @-

Explicação

  • Usa o utilitário mktemp(1) para (com segurança) criar um diretório de origem vazio e um arquivo de origem
  • A diretiva /set mtree define o padrão uid/gid/mode
  • O atributo content= especifica o conteúdo de origem para cada diretório / arquivo como a cópia temporária
  • @- lê a especificação da mtree de stdin
  • Deixa os arquivos mktemp para o sistema ser limpo (já que, por padrão, eles são criados no diretório "temp" do sistema - normalmente $TMPDIR ou /tmp )

Remova o | tar ... à direita para ver a especificação da mtree que é gerada.

Claro, substitua bsdtar por tar conforme necessário.

Os principais recursos dessa abordagem são usar mktemp para criar com segurança o arquivo e diretório temporários (o que evita ter que se preocupar com conflitos com arquivos existentes e encontrar um local seguro / adequado para criá-los) e apenas criar um de cada um para qualquer número de diretórios ou arquivos.

    
por 01.10.2017 / 05:23