Se eu entendi corretamente, você tem diretórios que contém arquivos chamados 1
, 2
, 3
, etc. (até um limite de variável) e você deseja substituir cada diretório por um arquivo que tenha o mesmo nome como o diretório, e é a concatenação dos arquivos em ordem numérica.
Nesta resposta, vou usar zsh , porque é muito mais fácil de usar do que uma combinação de bash e outros Ferramentas. Você pode traduzir o método para sh e find (o bash e o GNU find serão mais fáceis do que o sh simples e o POSIX find).
Primeiro, para localizar os diretórios, a presença de um ponto não parece ser uma heurística muito útil: você perderá arquivos cujo nome não contenha um ponto e você atingirá diretórios cujo nome contém um ponto . Procurar por diretórios que contenham arquivos nomeados numericamente parece mais confiável (embora não seja perfeito, nada é). Aviso: código não testado:
#!/bin/zsh
for dir in **/1(:h); do
files=($dir/*(Nn:t))
for ((i=1; i<=$#files; i++)); do
# if the ith file isn't called i, skip this directory
if [[ $files[i] != $i ]]; then files=; break; fi
done
if [[ -z $files ]]; then continue; fi
# The directory contains only numbered files, and they're in sequence.
# Concatenate the files, move the result into place and remove the directory.
tmp=$(TMPDIR=$dir:h mktemp -d)
mv -- $dir $tmp &&
for x in $tmp/$dir:t/$^files; do cat -- $x; done >$tmp/file &&
mv -- $tmp/file $dir &&
rm -r $tmp
done
Explicação dos recursos do zsh:
-
:t
e:h
são modificadores de expansão do histórico para obter a parte do diretório e o nome de base do um arquivo respectivamente. -
*(Nn)
usa qualificadores de glob :n
para classificar nomes de arquivos em ordem numérica de ordem lexicográfica eN
para obter uma matriz vazia em vez de um erro se o diretório estiver vazio. - O
^
parâmetro modificador de expansão em$dir/$^files
adiciona o prefixo$dir/
para cada elemento da matrizfiles
(em oposição a adicioná-lo apenas ao primeiro elemento).