Localizar com mkdir e substring

2

Eu tenho diretório com a próxima estrutura:

example
├───1
│   └───01-01-2015.txt
├───2
│   └───02-02-2016.txt
├───3
│   └───03-03-2017.txt
└───script.sh

Estou tentando escrever um script que encontrará todos os arquivos .txt e criará, além deles, uma nova pasta com um nome baseado no nome do arquivo .txt em uma determinada pasta.

O resultado será:

example
├───1
│   ├───01-01-2015
│   └───01-01-2015.txt
├───2
│   ├───02-02-2016
│   └───02-02-2016.txt
├───3
│   ├───03-03-2017
│   └───03-03-2017.txt
└───script.sh

Portanto, na pasta "3" subpasta "03-03-2017", na pasta "2" subpasta "02-02-2016", etc.

Eu entendo que encontrar todos os arquivos .txt é bastante simples, mas não consigo descobrir como combiná-lo com a criação de diretórios e a execução de substring para cada resultado de pesquisa.

Obrigado antecipadamente !!

    
por i474232898 19.01.2017 / 18:45

2 respostas

3

Gostaria apenas de usar um loop bash para isso:

for i in **/*.txt; do mkdir "${i%.txt}"; done

Se eu executar isso no seu exemplo, obtenho:

$ tree
.
├── 1
│   └── 01-01-2015.txt
├── 2
│   └── 02-02-2016.txt
└── 3
    └── 03-03-2017.txt

3 directories, 3 files
$ shopt -s globstar
$ for i in **/*.txt; do mkdir "${i%.txt}"; done
terdon@oregano foo $ tree
.
├── 1
│   ├── 01-01-2015
│   └── 01-01-2015.txt
├── 2
│   ├── 02-02-2016
│   └── 02-02-2016.txt
└── 3
    ├── 03-03-2017
    └── 03-03-2017.txt

6 directories, 3 files

globstar é uma opção bash, explicada em man bash :

globstar

If set, the pattern ** used in a pathname expansion context will match all files and zero or more directories and subdirectories. If the pattern is followed by a /, only directories and subdirectories match.

Assim, após habilitá-lo com shopt -s globstar , o padrão **/*.txt encontrará todos os arquivos (ou dirs) cujo nome termina com .txt .

O ${i%.txt} é a sintaxe da shell para remover uma substring. O formato geral é ${variable%string} e removerá a primeira instância de string do final da variável. Portanto, ${i%.txt}" será o nome do arquivo (incluindo diretórios pai), menos o .txt . Portanto, [passá-lo para mkdir criará o diretório desejado.

Pessoalmente, acho a sintaxe acima muito mais simples, mas veja como fazer isso com find :

find . -name '*.txt' -exec sh -c 'mkdir ${0%.txt}' {} \;

Aqui, o -exec command {} substituirá {} por cada um dos resultados de find e, em seguida, executará command nele. Como o comando aqui é uma chamada para sh -c , o sh assumirá o {} como seu parâmetro posicional zero, $0 . Então, nós executamos a mesma substituição de shell conforme explicado acima para criar o diretório.

    
por 19.01.2017 / 18:59
4
find example -name \*.txt | sed 's/\.txt$//' | xargs -n 1 mkdir

Aviso: isso exige que seus caminhos não contenham novas linhas.

Editar: veja o comentário de terdon se você estiver usando ferramentas GNU.

    
por 19.01.2017 / 19:03