Como criar vários arquivos com o terminal?

46

Estou aprendendo a programar com um livro introdutório muito legal para C e escrevo todos os exemplos e tarefas para aprender a sintaxe de cor. Fiz todos os arquivos manualmente até agora, mas clicar, nomear e salvar fica cansativo.

Eu preciso de uma maneira de criar vários arquivos, como bspl0001.c, bspl0002.c, bspl0003.c, etc. e salvá-las no diretório "learning_c" ou algo assim.

Eu sou um novato no Ubuntu / Linux e honestamente só o executo via VirtualBox porque o IDE Geany foi fácil de configurar. Portanto, eu realmente não sei como o Terminal funciona.

edit Acabei de me encontrar nesta conta antiga e estou sacudindo a cabeça sobre o motivo de querer aprender uma sintaxe de código de cor. Curiosamente, estou quase terminando meus estudos de CS / Math BSc. Muito obrigado pela ajuda em retrospectiva!

desdém
fonte
1
Por que criar todos os arquivos de uma só vez? O que realmente estou usando: pressione uma combinação de teclas para 1. ver no meu diretório de código qual deve ser o "próximo" arquivo, 2. criar o arquivo com o nome correto (incluindo shebang) e 3. abrir no meu editor (no meu caso) Ocioso). Tudo em uma tecla. Dessa forma, você evita muitos arquivos (ainda) não utilizados.
Jacob Vlijm

Respostas:

77

Você pode fazer isso com estes comandos:

mkdir learning_c
cd learning_c
touch bspl{0001..0003}.c

Explicação:


  • mkdir learning_c

    • Isso criará uma pasta chamada learning_cna pasta atual
    • A pasta atual geralmente é a sua pasta pessoal, também chamada ~
    • Você pode alterar o diretório atual usando o cdcomando (ie cd Desktop)
  • cd learning_c

    • Sim, você pode adivinhar, está entrando na pasta recém-criada
  • touch bspl{0001..0003}.c

    • touché uma ferramenta para criar arquivos vazios e modificar registros de data e hora; estamos criando arquivos vazios.
    • touch myfilecriará um arquivo vazio chamado myfile.
    • O código feio que se segue ( bspl{0001..0003}.c) é chamado de expansão entre chaves . Esse é um ótimo recurso do bashshell que permite criar longas listas de combinações arbitrárias de strings. Você pode aprender mais sobre isso no Bash Hackers Wiki . Nesse caso, você fará uma longa lista de parâmetros que serão passados ​​para touch. Você também pode usar seu equivalente longo:

      touch bspl0001.c bspl0002.c bspl0003.c
      
    • Você pode alterar o número de arquivos: se você quiser 12 arquivos, poderá executar bspl{0001..0012}.c.

    • Os zeros à esquerda (em 0012vez de 12) garantem que a saída use 4 dígitos preenchidos com zero.
Helio
fonte
4
Como alternativa, para salvar algumas teclas pressionadas,touch bspl000{1..3}.c
Reid
1
@ Reid: E o que acontece se o Herios quiser 10 ou mais arquivos?
Helio
3
Para aqueles que querem caixote uma lista de arquivos com a mesma extensãotouch {test,tes2,tes3}.js
Rick
1
@ Rick: Não é o que eu respondo? ;-) . Seu código pode ser simplificado:touch tes{t,2,3}.js
Helio
1
e você também pode fazer isso em uma linha de comando: $ mkdir learning_c; cd learning_c; toque em bspl000 {1,2,3,4} .c. O ";" ajudará você a adicionar comandos que serão executados em ordem um após o outro.
Pavlos Theodorou
4

Crie um arquivo (próximo) numerado corretamente com uma combinação de teclas de atalho

Por que criar todos os arquivos de uma só vez? A desvantagem é que você terá muitos arquivos vazios e não utilizados. O que estou realmente usando: pressione uma combinação de teclas para:

  1. faça com que um script veja no meu diretório de código qual deve ser o "próximo" arquivo,
  2. crie o arquivo nomeado corretamente (incluindo shebang) e
  3. abra o novo arquivo no meu editor (no meu caso, Idle).

Tudo em uma tecla. Dessa forma, você evita muitos arquivos (ainda) não utilizados; Os arquivos são criados apenas se você precisar deles.

Uma versão simplificada abaixo (não executando a etapa 3). Em cada pressionamento de tecla, ele criará um arquivo numerado corretamente, como:

bspl0001.c, bspl0002.c, bspl0003.c etc
#!/usr/bin/env python3
import os
#--- set your code directory below
dr = "/path/to/your/coding_files"
#--- set the desired (base) name extension and shebang below (leave it ""if you don't want an automatically set shebang)
name_initial = "bspl"
extension = ".c"
shebang = ""
#---

existing = os.listdir(dr)
n = 1
while True:
    file = dr+"/"+name_initial+str(n).zfill(4)+extension
    if os.path.exists(file):
        n = n+1
    else:
        with open(file, "wt") as out:
            out.write(shebang)
        break

Como usar

  1. Copie o script em um arquivo vazio
  2. Na seção principal, defina o caminho para o seu diretório (e opcional: altere o nome da base e / ou extensão, shebang).
  3. Salve o script como create_empty.py
  4. Execute o script a partir de um atalho: Configurações do sistema> Teclado> Atalhos personalizados. Adicione o comando:

    python3 /path/to/create_empty.py
    
Jacob Vlijm
fonte
3

Você pode usar o seguinte código python, modificá-lo para atender às suas necessidades.
Salve o seguinte código com o nome do arquivofilecreator.py

#!/usr/bin/env python
import os
import subprocess
work_path = os.path.abspath(os.path.dirname(__file__))
if not os.path.exists("learning_c"):
    os.mkdir("learning_c")
os.chdir(os.path.expanduser(work_path+"/learning_c"))
n = 10 #put the number as you wish
for i in range(n):
    subprocess.call(['touch', "bsdl"+str(i).zfill(4)+".c"])

E, em seguida, execute-o com este comando:

python filecreator.py
Bolzano
fonte
2

O bashcaminho é bom, mas e se você estiver trabalhando com um shell que não suporta a expansão de chaves? touch file{1..10}não funciona para mim, mkshpor exemplo. Aqui estão três maneiras alternativas que funcionam independentemente do shell.

seq

Uma abordagem mais neutra ao shell seria combinar o seqcomando para gerar a sequência de números formatados com as printfopções e passá-lo ao xargscomando. Por exemplo,

$ ls -l
total 0
$ seq -f "%04.0f" 10 | xargs -I "{}" touch bspl"{}".c                 
$ ls
bspl0002.c  bspl0004.c  bspl0006.c  bspl0008.c  bspl0010.c
bspl0001.c  bspl0003.c  bspl0005.c  bspl0007.c  bspl0009.c

Perl

Obviamente, o Perl, sendo uma ferramenta * nix bastante difundida, também pode fazer isso. O comando de uma linha específico que temos aqui é o seguinte:

perl -le 'do { $var=sprintf("%s%04d.c",$ARGV[0],$_ ); open(my $fh, ">", $var);close($fh) } for $ARGV[1] .. $ARGV[2]' bslp 1 5 

Efetivamente, o que acontece aqui é que especificamos três argumentos de linha de comando: prefixo do nome do arquivo, índice inicial e final. Em seguida, usamos do { } for $ARGV[1] .. $ARGV[2]a iteração para um intervalo específico de números. Digamos, $ARGV[1]tinha 5 e $ARGV[2]9, iteraríamos mais de 5,6,7,8 e 9.

O que acontece em cada iteração nos chavetas? pegamos cada número especificado com $_e, usando a sprintf()função, criamos uma string m que emenda o prefixo (primeiro argumento da linha de comando $ARGV[0]) e o número fornecido, mas preenche o número com 4 zeros (o que é feito pelo printfestilo de formatação, %04dpart) e anexe o .csufixo. Como resultado, em cada iteração, criamos um nome como bspl0001.c.

Ele open(my $fh, ">", $var);close($fh)atua efetivamente como touchcomando, criando um arquivo com nome especificado.

Embora um pouco longo, ele tem um desempenho muito bom, de maneira semelhante ao script python de Jacob Vlijm. Também pode ser convertido em um script para facilitar a leitura, se desejado, da seguinte maneira:

#!/usr/bin/env perl
use strict;
use warnings;

for my $i ( $ARGV[1] .. $ARGV[2] ) { 
    my $var=sprintf("%s%04d.c",$ARGV[0],$i ); 
    open(my $fh, ">", $var) or die "Couldn't open " . $var ;
    close($fh) or die "Couldn't close " . $var ;
}

Vamos testar isso. Primeiro o one-liner:

$ ls -l
total 0
$ perl -le 'do { $var=sprintf("%s%04d.c",$ARGV[0],$_ ); open(my $fh, ">", $var);close($fh) } for $ARGV[1] .. $ARGV[2]' bslp 1 5
$ ls -l                                                                                               
total 0
-rw-rw-r-- 1 xieerqi xieerqi 0 2月   5 23:36 bslp0001.c
-rw-rw-r-- 1 xieerqi xieerqi 0 2月   5 23:36 bslp0002.c
-rw-rw-r-- 1 xieerqi xieerqi 0 2月   5 23:36 bslp0003.c
-rw-rw-r-- 1 xieerqi xieerqi 0 2月   5 23:36 bslp0004.c
-rw-rw-r-- 1 xieerqi xieerqi 0 2月   5 23:36 bslp0005.c

E agora o script:

$ ls -l
total 4
-rwxrwxr-x 1 xieerqi xieerqi 244 2月   5 23:57 touch_range.pl*
$ ./touch_range.pl bspl 1 5                                                                           
$ ls -l
total 4
-rw-rw-r-- 1 xieerqi xieerqi   0 2月   5 23:58 bspl0001.c
-rw-rw-r-- 1 xieerqi xieerqi   0 2月   5 23:58 bspl0002.c
-rw-rw-r-- 1 xieerqi xieerqi   0 2月   5 23:58 bspl0003.c
-rw-rw-r-- 1 xieerqi xieerqi   0 2月   5 23:58 bspl0004.c
-rw-rw-r-- 1 xieerqi xieerqi   0 2月   5 23:58 bspl0005.c
-rwxrwxr-x 1 xieerqi xieerqi 244 2月   5 23:57 touch_range.pl*

awk

Outra abordagem seria awk, executando um loop for, redirecionando para um arquivo específico. A abordagem é semelhante ao one-liner perl com argumentos de linha de comando. Embora awkseja principalmente um utilitário de processamento de texto, ele ainda pode fazer uma programação interessante do sistema.

$ awk 'BEGIN{for(i=ARGV[2];i<=ARGV[3];i++){fd=sprintf("%s%04d.c",ARGV[1],i); printf "" > fd;close(fd)}}' bslp 1 5
Sergiy Kolodyazhnyy
fonte