Как удалить все каталоги, кроме последних 2 каталогов, и символическую ссылку, указывающую на эти каталоги

#linux #bash #shell #unix #scripting

#linux #bash #оболочка #unix #сценарии

Вопрос:

У меня ниже структура каталогов.

 ~/test_dir🍺$ls -lrt
total 8
drwxr-xr-x  5 kk  Users   160B Apr 17 23:53 app1/
drwxr-xr-x  5 kk  Users   160B Apr 17 23:53 app2/
drwxr-xr-x  5 kk  Users   160B Apr 17 23:53 app3/
drwxr-xr-x  5 kk  Users   160B Apr 17 23:53 app4/
drwxr-xr-x  5 kk  Users   160B Apr 17 23:53 app5/

~/test_dir🍺$cd app1

~/test_dir/app1🍺$ls -rlt
total 0
drwxr-xr-x  2 kk  10677    64B Apr 19 14:16 release1/
drwxr-xr-x  2 kk  10677    64B Apr 19 14:16 release2/
drwxr-xr-x  2 kk  10677    64B Apr 19 14:16 release3/
drwxr-xr-x  2 kk  10677    64B Apr 19 14:16 release4/
drwxr-xr-x  2 kk  10677    64B Apr 19 14:17 release5/
drwxr-xr-x  2 kk  10677    64B Apr 19 14:17 relase23/
drwxr-xr-x  2 kk  10677    64B Apr 19 14:17 release8.9/
lrwxr-xr-x  1 kk  10677     8B Apr 19 14:18 Current@ -> release4

~/test_dir🍺ls -t1 | tail -n  3 | grep -v Current
relase23/
release5/
release4/
release3/
release2/
release1/
 

Как сохранить или сохранить только последние два каталога, которые были недавно изменены, включая символические ссылки и их соответствующие каталоги, указывающие на них?

Я попробовал следующее

 ~/test_dir🍺ls -t1 | tail -n  3 | grep -v Current 
relase23/
release5/
release4/
release3/
release2/
release1/

~/test_dir/app1🍺$ls -t1 | tail -n  3 | grep -v Current | xargs rm -r
~/test_dir/app1🍺$ls -rlt
total 0
drwxr-xr-x  2 kk  10677    64B Apr 19 14:17 release8.9/
lrwxr-xr-x  1 kk  10677     8B Apr 19 14:18 Current@ -> release4
 

но этот даже удаляет каталоги, указывающие на символическую ссылку, сохраняя только неработающую символическую ссылку.

 
#!/bin/bash
array=("app1" "app2" "app3" "app4" "app5")

for ((i=0;i<${#array[@]};i  ))
do
app=${array[$i]}
echo "the app dir name is: $app"
cd ~/test_dir/$app
count=$(ls -t1 | tail -n  4 | grep -v Current | wc -l)
echo "number of directories deleted are:"
if [ $count == 0 ]
then
echo "Nothing to delete"
echo " "
else
ls -t1 | tail -n  4 | grep -v Current| xargs rm -r
fi
done
exit
 

Ожидаемые результаты

 ~/test_dir/app1🍺$ls -t1 | tail -n  3 | grep -v Current | xargs rm -r
~/test_dir/app1🍺$ls -rlt
total 0
drwxr-xr-x  2 kk  10677    64B Apr 19 14:16 release4/
drwxr-xr-x  2 kk  10677    64B Apr 19 14:17 release8.9/
lrwxr-xr-x  1 kk  10677     8B Apr 19 14:18 Current@ -> release4
 

release4/ не должен удаляться, что указывает на символическую ссылку и символическую ссылку тоже. Спасибо за любую помощь.

Комментарии:

1. Откуда взялась эта пивная икона? Этот формат кода поддерживает смайлики?

2. Пожалуйста, проверьте существующие ответы и уточните ваши требования.

3. echo -e » xF0 x9f x8d xba» даст вам значок пива

Ответ №1:

Предположения:

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

 kept=0
stat -c "%Y %n %F" * | sort -rn |
while read timestamp dir type
do [[ directory == "$type" ]] || continue
   ls -ld $dir/ # for logging only 
   if (( kept   < 2 ))
   then echo "Keeping $dir"
   else echo "Removing $dir"
        rm -fr $dir
   fi
done
 

Это вообще не будет касаться символических ссылок, хотя мы могли бы добавить это, если вы этого хотите. То же самое верно и для обычных файлов и т.д.

Не разбирайте ls

Комментарии:

1. Это неправильно в 2-х отношениях: 1) Он не удаляет «relase23». 2) Он удаляет «release4».

2. 1) Это сделано намеренно. Он явно пропускает «relase23» как не соответствующий соглашению об именовании. Легко удалить release , из release* которого он будет применяться ко всем подкаталогам, если это предпочтительнее. 2) Он успешно сохранен release4 в моих тестах, основываясь на времени модификации . Кто-нибудь еще видит такую же ошибку, если после создания всех подкаталогов вы касаетесь файла в release4 и release8.9 ?

3. 1) «Ожидаемые результаты», как указано, показывают, что relase23 удален. 2) release4 старше 5, 23 и 8.9. Таким образом, он удаляется. Но даже если он будет более новым: ваш код не отражает каталог, на который указывает Current@ .

4. Именно поэтому я указал предположения и результаты, отличные от ОП, что показалось мне опечаткой. Все еще жду отзывов от заявителя о деталях, которые я уточню до спецификации, когда спецификация будет ясна.

5. Мои каталоги не имеют общих форматов имен, которые я привел для примера. В каталоге была опечатка relase23/ это должен быть release23/

Ответ №2:

 SKIP="$(readlink Current@)";ls -trd release*|grep -v "^$SKIP$"|head -n -1|while read f;do rm -rf rela* "$f";done
 

РЕДАКТИРОВАТЬ 2:

OP немного изменил спецификацию: есть и другие каталоги.

 18.09/ 19.01/ 19.02/ 19.03/ 19.05/ 19.04/
 

Я немного изменил «однострочник», чтобы также зафиксировать ЭТО:

 [user123@matrix app1]$ mkdir 18.09/ 19.01/ 19.02/ 19.03/ 19.05/ 19.04/
[user123@matrix app1]$ ls -ltr
insgesamt 28
drwxrwxr-x. 2 user123 user123 4096 19. Apr 14:16 release4
lrwxrwxrwx. 1 user123 user123    8 19. Apr 14:18 Current@ -> release4
-rw-rw-r--. 1 user123 user123    0 20. Apr 01:45 1
drwxrwxr-x. 2 user123 user123 4096 20. Apr 01:48 19.05
drwxrwxr-x. 2 user123 user123 4096 20. Apr 01:48 19.04
drwxrwxr-x. 2 user123 user123 4096 20. Apr 01:48 19.03
drwxrwxr-x. 2 user123 user123 4096 20. Apr 01:48 19.02
drwxrwxr-x. 2 user123 user123 4096 20. Apr 01:48 19.01
drwxrwxr-x. 2 user123 user123 4096 20. Apr 01:48 18.09
[user123@matrix app1]$ SKIP="$(readlink Current@)";ls -tr|egrep -v "^$SKIP$|^Current@$"|head -n -1|while read f;do rm -rf "$f";done
[user123@matrix app1]$ ls -l
insgesamt 8
drwxrwxr-x. 2 user123 user123 4096 20. Apr 01:48 18.09
lrwxrwxrwx. 1 user123 user123    8 19. Apr 14:18 Current@ -> release4
drwxrwxr-x. 2 user123 user123 4096 19. Apr 14:16 release4
[user123@matrix app1]$
 

Комментарии:

1. Добавьте файлы в release4 и release8.9 , и они будут иметь более поздние времена модификации.

2. Добавление файла просто установит ТЕКУЩЕЕ время в каталоге. И, как вы видите, у каталогов те же временные метки, что и у вас. Для меня нет проблем с установкой временных меток каталогов. Но ВАШИ временные метки имеют только временные метки с разрешением до минуты. Лучше используйте что-то вроде «date % s -r release4», если вы хотите получить ТОЧНЫЕ предварительные условия и ответ. Тем не менее: мое решение соответствует вашим критериям приемлемости. 🙂

3. OP указал «последние два каталога, которые были недавно изменены». Я использую stat with %Y, который предоставляет временные метки изменения эпохи для второго.

4. Вы уже упоминали о синтаксическом анализе. На самом деле информация в предоставленном документе тривиальна. И это общая информация. На самом деле здесь нет проблем с использованием ls в данной спецификации. Он предлагает решение «one liner».

5. статистика с %Y не имеет значения. пользователь8895496 не использовал его. И ls также учитывает разрешение second. Попробуйте это: «touch -d ‘ @ 0’ 1; touch -d ‘ @1’ 2; touch -d ‘ @0’ 3; ls -t?»