Você tem arquivos que basicamente têm um caminho de destino codificado em seus nomes de arquivos.
O arquivo chamado A_20180423_0015
deve ser movido para A/20180423/0015
(suponho que 0015
é o novo nome do arquivo no diretório A/20180423
), que é um nome de caminho que é o mesmo que o original nome do arquivo, mas com os sublinhados substituídos por barras.
Isso significa que este exercício é sobre a substituição de caracteres em strings.
Não há necessidade de passar e criar diretórios de destino para cada data possível, porque o destino já está codificado no nome do arquivo dos arquivos.
Não tenho certeza absoluta de onde os arquivos originais estão localizados, ou se você pode usar apenas [A-Z]_*_*
como um padrão para combiná-los no diretório atual (vou assumir que você pode).
for source_filename in [A-Z]_*_*; do
target_pathname=${source_filename//_//}
mkdir -p "${target_pathname%/*}"
mv "$source_filename" "$target_pathname"
done
Se começarmos com
.
|-- A_20180423_0015
|-- B_20180501_0045
'-- C_20180426_0045
0 directory, 3 files
... e execute o código acima, depois terminaremos com
.
|-- A/
| '-- 20180423/
| '-- 0015
|-- B/
| '-- 20180501/
| '-- 0045
'-- C/
'-- 20180426/
'-- 0045
6 directories, 3 files
Código anotado:
# Loop over all names in the current directory that matches the given pattern.
for source_filename in [A-Z]_*_*; do
# Replace all underscores in the found name with slashes.
# We use bash's ${parameter//pattern/replacement} pattern substitution
# to do this.
# If you need to append a path to this, just do so with
# target_pathname="/some/path/${source_filename//_//}"
target_pathname=${source_filename//_//}
# Make sure that the target directory exists.
# With ${target_pathname%/*} we remove the filename component of
# the target pathname to get the directory of the destination file.
# You may change this to the following if you wish:
# mkdir -p "$( dirname "$target_pathname" )"
mkdir -p "${target_pathname%/*}"
# Move the file into place.
mv "$source_filename" "$target_pathname"
done
Se eu entendi mal a questão e os arquivos devem manter seus nomes de arquivo originais, mas sejam movidos para diretórios correspondentes ao nome do arquivo, ou seja, A_20180423_0015
deve ser movido para A/20180423/0015/A_20180423_0015
, só precisamos alterar alguns caracteres o código acima:
mkdir -p "${target_pathname%/*}"
muda para
mkdir -p "$target_pathname"
Essa mudança nos daria
.
|-- A/
| '-- 20180423/
| '-- 0015/
| '-- A_20180423_0015
|-- B/
| '-- 20180501/
| '-- 0045/
| '-- B_20180501_0045
'-- C/
'-- 20180426/
'-- 0045/
'-- C_20180426_0045
9 directories, 3 files
Para o caso em que os arquivos de origem estão localizados em outro diretório que não o atual:
for source_pathname in /some/source/path/[A-Z]_*_*; do
source_filename=${source_pathname##*/}
target_pathname="some/target/path/${source_filename//_//}"
mkdir -p "$target_pathname"
mv "$source_pathname" "$target_pathname"
done