скопіювати файли та додати в інший каталог?


1

У мене є п’ять каталогів Dir1, Dir2, Dir3, Dir4, Dir5. У кожному каталозі я маю п'ять текстових файлів (які названі як file1.txt, file2.tx, .file5.txt), які містять дані. Мені потрібно скопіювати file1.txt з усіх п'яти каталогів і додати їх один за одним в інший каталог (названий як Joint_Dir). Зробіть те ж саме файл2.txt, file3.txt ... file5.txt.

Відповіді:


2

Зробити це можна за допомогою шаблонів глобусів / марок . Наприклад, наведене нижче об'єднає всі 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

Проте випробував обидва коди, проте, він копіює file1.txt в Dir1 більше і більше 5 разів. аналогічно, файл2.txt Dir1 додається 5 разів. Я хочу, щоб файл file1.txt Dir2 був розміщений нижче файлу1.txt Dir1. так само і для інших файлів і каталогів.
Амер

Який результат ls Dir[1..5]/file1.txt?
igal

DIR1 / FLOW_OUT_1.txt DIR2 / FLOW_OUT_1.txt DIR3 / FLOW_OUT_1.txt DIR4 / FLOW_OUT_1.txt DIR5 / FLOW_OUT_1.txt. Я називаю реж. DIR. Крім того , file1.txt насправді мій FLOW_OUT_1.txt
Ameer

Отже, як бачите, ви отримуєте правильний список файлів для конкатенації, ні? Ви двічі перевірили, чи містять у цих файлах текст, який, на вашу думку, слід?
igal

Справді. Я отримую правильний список, проте коли я запускаю ваш код для конкатенації, він випилює результат, коли FLOW_OUT_1.txt з DIR1 об'єднується п'ять разів. Я ще раз перевірив файли, чи вони правильні.
Амеєр
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.