Você pode fazer isso com globbing-patterns / wildcards . Por exemplo, o seguinte irá concatenar todos os arquivos file1.txt
em um único arquivo no diretório Joint_Dir
:
cat Dir[1-5]/file1.txt > Joint_Dir/file1.txt
Mas antes de usar a correspondência de padrões para executar comandos como este, eu executaria alguns comandos de verificação de sanidade para verificar quais arquivos seriam afetados. Nesse caso, você pode verificar se o padrão Dir[1-5]/file1.txt
corresponde aos arquivos esperados usando ls
:
ls -ld Dir[1-5]/file1.txt
Outra opção seria usar a expansão de chaves . Reescrevendo o exemplo anterior usando a expansão de contraventamento, obtém-se o seguinte:
cat Dir{1..5}/file1.txt > Joint_Dir/file1.txt
Observe que a expansão de chave é um chamado bashism e pode não funcionar em um shell diferente. Esta distinção foi discutida noutro local, p. A expansão de chaves não funciona em um script . Como discutido nesse post, outras alternativas incluem o uso do comando seq
ou o incremento de uma variável dentro de um loop while.
Falando em loops, se você quiser realizar todas as concatenações em um único comando, pode usar um loop, por exemplo:
for i in $(seq 1 5); do
cat Dir[1-5]/file${i}.txt > Joint_Dir/file${i}.txt
done
O que se segue é um exemplo auto-contido ilustrando como usar a técnica acima. Você deve ser capaz de executar o seguinte como está. Primeiro, aqui está um script para configurar um diretório com arquivos de teste espelhando o que foi descrito na pergunta original:
#!/bin/bash
# create-test-files.sh
# Create test files and directories
for i in $(seq 1 5); do
mkdir -p "/tmp/test/Dir${i}"
for j in $(seq 1 5); do
echo "File ${j} in directory ${i}" > "/tmp/test/Dir${i}/file${j}.txt"
done
done
Depois de executar este script, podemos verificar o que acaba de ser criado:
$ bash create-test-files.sh
$ tree /tmp/test/
/tmp/test/
|-- Dir1
| |-- file1.txt
| |-- file2.txt
| |-- file3.txt
| |-- file4.txt
| '-- file5.txt
|-- Dir2
| |-- file1.txt
| |-- file2.txt
| |-- file3.txt
| |-- file4.txt
| '-- file5.txt
|-- Dir3
| |-- file1.txt
| |-- file2.txt
| |-- file3.txt
| |-- file4.txt
| '-- file5.txt
|-- Dir4
| |-- file1.txt
| |-- file2.txt
| |-- file3.txt
| |-- file4.txt
| '-- file5.txt
'-- Dir5
|-- file1.txt
|-- file2.txt
|-- file3.txt
|-- file4.txt
'-- file5.txt
5 directories, 25 files
Também podemos verificar o conteúdo dos arquivos:
$ cat /tmp/test/Dir[1-5]/file1.txt
File 1 in directory 1
File 1 in directory 2
File 1 in directory 3
File 1 in directory 4
File 1 in directory 5
$ cat /tmp/test/Dir1/file[1-5].txt
File 1 in directory 1
File 2 in directory 1
File 3 in directory 1
File 4 in directory 1
File 5 in directory 1
Em seguida, podemos criar o seguinte script para concatenar os arquivos:
#!/bin/bash
# concatenate-test-files.sh
# Create output directory
mkdir -p /tmp/test/Joint_Dir
# Concatenate identically-named files from different directories
for i in $(seq 1 5); do
cat "/tmp/test/Dir"[1-5]"/file${i}.txt" > "/tmp/test/Joint_Dir/file${i}.txt"
done
Depois de executar este script, podemos verificar o conteúdo do diretório de saída:
$ bash concatenate-test-files.sh
$ ls -1 /tmp/test/Joint_Dir/
file1.txt
file2.txt
file3.txt
file4.txt
file5.txt
$ cat /tmp/test/Joint_Dir/file1.txt
File 1 in directory 1
File 1 in directory 2
File 1 in directory 3
File 1 in directory 4
File 1 in directory 5
Assim que terminarmos de experimentar, podemos excluir o diretório de teste:
rm -rf /tmp/test