Виключення певних файлів і каталогів при видаленні файлів


11

Мій каталог верхнього рівня data. dataвключає декілька каталогів, і ці каталоги мають підкаталоги. Мені потрібно видалити всі файли та каталоги всередині, data/за винятком кількох файлів у деяких каталогах.

Наприклад, дані включають каталоги 100та 101. Я просто хочу , щоб зберегти a.txtі b.txtфайли 100/і c.txtта d.txtфайли 101/при видаленні всіх інших файлів і каталогів в 100і 101.

Приклад:

.
├── 100
   ├── a.txt
   ├── b.txt
   ├── c.txt
   └── d.txt
└── 101
    ├── a.txt
    ├── b.txt
    ├── c.txt
    └── d.txt

Я використовую rm -rf !(a.txt|b.txt)команду, але не можу застосувати цю команду для кожного каталогу автоматично.

Відповіді:


12

Як ви вже дізналися, ви можете використовувати extglobфункцію, яка увімкнена за допомогою:

shopt -s extglob

Це дозволяє виключити відповідність, щоб ви могли робити такі речі, як:

rm 100/!([ab].txt) 101/!([cd].txt)

Це добре спробувати echoспершу. Цей приклад буде відповідати будь- 100/якому, всередині якого немає a.txtабо b.txtі все, 101/що не є c.txtабо d.txt. Якщо для вас 100/застосовуються ті самі правила 102/, наприклад, ви можете:

10[02]/!([ab].txt) # or
{100,102}/!([ab].txt)

Я щойно наводив приклад для 100 та 101 каталогів, але насправді кількість підкаталогів становить майже 20. Чи є спосіб реалізувати вищевказаний код для кожного каталогу, не записуючи ім'я кожного каталогу в головну папку?
deepblue

@deepblue Будь ласка, надайте точний приклад для цього у своєму запитанні ( редагуйте ), особливо незрозуміло, як rmслід знати, які файли зберігати в яких каталогах, якщо ви не бажаєте цього вказувати.
десерт

7

Ви можете використовувати findдля цього. Ви можете звести на немає тестів в findс -notабо !. Це виключить сірники, а не їх знаходження.

Ви повинні бути обережними, щоб не видалити жоден з батьківських каталогів файлів, які ви хочете зберегти, особливо поточний каталог . , тому переконайтеся, що ви ретельно прочитали вихід, перш ніж видаляти.

На основі вашого прикладу ви можете зробити щось подібне з dataкаталогу.

find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt"

Додайте ! -path ./path/to/dirбудь-який шлях, який ви хочете уникнути видалення. Ви можете використовувати такі метахарактеристики *, але переконайтесь, що ви цитуєте це вираження, наприклад "./path*dir", для запобігання будь-яких небажаних розширень.

findза замовчуванням є рекурсивним. Навіть якщо ми не знайдемо ./100тут, ми знайдемо весь його вміст, якщо вони не відповідають шаблону [ab].txt. Якщо ви не можете зіставити всі імена, які ви хочете зберегти, додайте ще один тест:

! -path "./100/[ab].txt" ! -path ./100/foo

Це не буде знайти a.txtабо b.txtабо foo, але він знайде всі інші файли.

Коли ви впевнені, що бачите те, що хочете, можете додати -deleteдо кінця, щоб видалити знайдені файли:

find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt" -delete
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.