#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
Это вообще не будет касаться символических ссылок, хотя мы могли бы добавить это, если вы этого хотите. То же самое верно и для обычных файлов и т.д.
Комментарии:
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?»