Зробити це можна за допомогою шаблонів глобусів / марок . Наприклад, наведене нижче об'єднає всі file1.txt
файли в один файл у Joint_Dir
каталозі:
cat Dir[1-5]/file1.txt > Joint_Dir/file1.txt
Але перед тим, як використовувати відповідність шаблонів для виконання таких команд, я би запустив пару команд перевірки правильності, щоб перевірити, які файли будуть впливати. У цьому випадку ви можете перевірити, чи шаблон Dir[1-5]/file1.txt
відповідає очікуваним файлам, використовуючи ls
:
ls -ld Dir[1-5]/file1.txt
Іншим варіантом буде використання розширення дужок . Перезапис попереднього прикладу за допомогою розширення дужок дає наступне:
cat Dir{1..5}/file1.txt > Joint_Dir/file1.txt
Зауважте, що розширення дужок є так званим башизмом і може не працювати в іншій оболонці. Ця різниця обговорювалася в інших місцях, наприклад, розширення Brace не працює в сценарії . Як обговорюється в цій публікації, інші альтернативи включають використання seq
команди або збільшення змінної всередині циклу while.
Якщо говорити про петлі, якщо ви хочете виконати всі конкатенації в одній команді, ви можете використовувати цикл for, наприклад:
for i in $(seq 1 5); do
cat Dir[1-5]/file${i}.txt > Joint_Dir/file${i}.txt
done
Далі йде автономний приклад, що ілюструє, як використовувати вищевказану техніку. Ви повинні мати змогу запустити таке, як є. По-перше, ось сценарій для установки каталогу з тестовими файлами, що відображає те, що було описано в оригінальному запитанні:
#!/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
Після запуску цього сценарію ми можемо перевірити, що тільки що створено:
$ 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
Ми також можемо перевірити вміст файлів:
$ 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
Далі ми можемо створити наступний скрипт для об'єднання файлів:
#!/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
Після запуску цього сценарію ми можемо перевірити вміст вихідного каталогу:
$ 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
Після того, як ми закінчимо експерименти, ми можемо видалити тестовий каталог:
rm -rf /tmp/test