Форум программистов, компьютерный форум, киберфорум
Наши страницы
Shell, Bash
Войти
Регистрация
Восстановить пароль
 
IlyaLinux
8 / 8 / 4
Регистрация: 06.04.2016
Сообщений: 127
1

Удалить файлы по сгенерированному списку с проверкой на существование

08.11.2019, 17:46. Просмотров 258. Ответов 14
Метки нет (Все метки)

Здравствуйте, друзья!

Составляю команду, которая удалит файлы по сгенерированному списку с предварительной проверкой на существование, чтобы rm не ругалась, когда ее просят удалить несуществующий файл. Ключ -f не годится, нужно получить подтверждение пользователя об удалении.

Bash
1
2
3
$ echo file.{tgz,sht} file_prev.lnk | xargs -n1 -p -I FILE test ! -e FILE && rm -i FILE
test ! -e file.tgz file.sht file_prev.lnk ?...y
rm: невозможно удалить 'FILE': Нет такого файла или каталога
xargs не везде осуществила подстановку, можно преодолеть?
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.11.2019, 17:46
Ответы с готовыми решениями:

14

spilva
41 / 41 / 2
Регистрация: 02.11.2012
Сообщений: 233
08.11.2019, 19:45 2
Привет!
Есть несколько путей:

Bash
1
for line in `echo file.{tgz,sht} file_prev.lnk`; do test -e $line && rm -i $line; done
Но если очень хочется xargs, то

Bash
1
echo file.{tgz,sht} file_prev.lnk | xargs -d $' ' -n 1 -p -I FILE sh -c 'test -e FILE && rm -i FILE'
Я в таких случаях предпочитаю использовать заранее сгенерированный файл, так легче работать.
1
nezabudka
1057 / 422 / 153
Регистрация: 28.06.2015
Сообщений: 962
Записей в блоге: 15
08.11.2019, 22:53 3
Bash
1
rm -i $(ls file.{tgz,sht} file_prev.lnk 2>/dev/null)
0
nezabudka
1057 / 422 / 153
Регистрация: 28.06.2015
Сообщений: 962
Записей в блоге: 15
09.11.2019, 10:41 4
Bash
1
rm -i "$(ls file.{tgz,sht} file_prev.lnk 2>/dev/null)"
0
09.11.2019, 10:41
IlyaLinux
8 / 8 / 4
Регистрация: 06.04.2016
Сообщений: 127
11.11.2019, 14:20  [ТС] 5
Переделал в соответствии с рекомендациями и тут дошло, что совсем забыл про пробелы. Новый вариант.

Bash
1
2
3
4
5
6
7
#sudo touch "file name"{.tgz,_prev.lnk}
 
echo "'file name"{.tgz,.sht,_prev.lnk}"'" | xargs -n 1 \
| while read line; do
    echo "$line"
    if [ -e "$line" ]; then rm -i "$line"; fi
done
Цикл for в bash топорно дробит по пробелам, даже если они заключенны в кавычки, пришлось искать альтернативу. К счастью, xargs отработал ожидаемо. Скрипт, наконец, заработал, но есть ошибки.

Bash
1
2
3
4
$ ./test.sh 
file name.tgz
rm: удалить защищенный от записи пустой обычный файл 'file name.tgz'? file name_prev.lnk
rm: удалить защищенный от записи пустой обычный файл 'file name_prev.lnk'? $
Нет возможности ответить на вопрос от rm. Тут же выводится следующий вопрос, за ним следующий, и так пока не кончится список. Подскажи почему это происходит? Неужели, в цикле нельзя использовать rm -i ?
0
nezabudka
1057 / 422 / 153
Регистрация: 28.06.2015
Сообщений: 962
Записей в блоге: 15
11.11.2019, 16:36 6
IlyaLinux, Это очень просто, потому что команда rm использует для вывода подтверждения
stderr. Выбирайте варианты
Bash
1
2
3
(IFS=$'\n'; rm -i $(ls *.tgz *.sht *_prev.lnk 2>/dev/null))
(IFS=$'\n'; rm -i $(shopt -s extglob; ls *@(.tgz|.sht|_prev.lnk)))
(IFS=$'\n'; rm -i $(compgen -f -X '!(*.tgz|*.sht|*_prev.lnk)'))
0
IlyaLinux
8 / 8 / 4
Регистрация: 06.04.2016
Сообщений: 127
11.11.2019, 17:52  [ТС] 7
nezabudka, благодарю за подсказки, они развивают. Варианты с *.tgz *.sht *_prev.lnk не годятся, т.к. в папке будут файлы с другими именами и такими же расширениями. Это скрипт для резервного копирования. Он работает в пределах одного раздела и именем файла является метка этого раздела. Архив может быть инкрементным, поэтому кроме самого архива появились дополнительные файлы .sht - snapshot раздела, _prev.lnk - ссылка на предыдущий архив, чтобы построить цепочку файлов для восстановления. Как выяснилось, метки разделов могут содержать пробелы, поэтому скрипт должен быть пробелоустойчивым и удалять архивы только тех разделов, которые выбраны для архивации.

В меру моих скромных способностей, немного помучившись все же удалось сгенерировать список, где каждый файл напечатан с новой строчки. А вот обойти его и удалить с проверкой не выходит.
0
volodin661
2235 / 1020 / 169
Регистрация: 10.12.2013
Сообщений: 3,439
11.11.2019, 18:13 8
Bash
1
perl -lne unlink list
где list - это файл со списком

Добавлено через 38 секунд
уверяю, всё будет тихо, как на кладбище.
0
IlyaLinux
8 / 8 / 4
Регистрация: 06.04.2016
Сообщений: 127
11.11.2019, 18:22  [ТС] 9
Цитата Сообщение от volodin661 Посмотреть сообщение
уверяю, всё будет тихо, как на кладбище.
. Нужно наоборот, чтобы не тихо, а громко, и по каждому файлу из списка спросил. Если стоит задача удалить тихо, подойдет простой rm -f.
0
volodin661
2235 / 1020 / 169
Регистрация: 10.12.2013
Сообщений: 3,439
11.11.2019, 18:35 10
или ты нас тут за дураков держишь или у тебя проблемы с составлением задания на русском языке.
Цитата Сообщение от IlyaLinux Посмотреть сообщение
Составляю команду, которая удалит файлы по сгенерированному списку с предварительной проверкой на существование, чтобы rm не ругалась, когда ее просят удалить несуществующий файл.
0
IlyaLinux
8 / 8 / 4
Регистрация: 06.04.2016
Сообщений: 127
11.11.2019, 19:19  [ТС] 11
volodin661, зачем ругаться. Если прочтете далее по тексту
Цитата Сообщение от IlyaLinux Посмотреть сообщение
Ключ -f не годится, нужно получить подтверждение пользователя об удалении.
0
skouzmine
40 / 34 / 14
Регистрация: 27.02.2016
Сообщений: 159
11.11.2019, 19:31 12
@IlyaLinux
может субшел поможет и вам помоему правильно говорили избавиться от заргз

Код
for F in $(ваш список файлов кандидатов) ; do (rm -i $F) ;  done
0
volodin661
2235 / 1020 / 169
Регистрация: 10.12.2013
Сообщений: 3,439
11.11.2019, 20:11 13
Bash
1
perl -lne 'if (-e) {print"$_: удалить?"; unlink or warn "$_: $!" if <STDIN> =~ m(^y|д)i}' list
0
IlyaLinux
8 / 8 / 4
Регистрация: 06.04.2016
Сообщений: 127
Сегодня, 11:27  [ТС] 14
Цитата Сообщение от skouzmine Посмотреть сообщение
может субшел поможет
Увы, работает также.
Bash
1
2
3
4
$ ./test.sh 
file name.tgz
rm: удалить защищенный от записи пустой обычный файл 'file name.tgz'? file name_prev.lnk
rm: удалить защищенный от записи пустой обычный файл 'file name_prev.lnk'? $
Цитата Сообщение от skouzmine Посмотреть сообщение
правильно говорили избавиться от заргз
в последней редакции избавился. Он используется выше для генерации списка, а обход делает while read.

Добавлено через 4 минуты
Цитата Сообщение от volodin661 Посмотреть сообщение
Bash
1
perl -lne 'if (-e) {print"$_: удалить?"; unlink or warn "$_: $!" if <STDIN> =~ m(^y|д)i}' list
Это уже другой язык. Неужели на могучем bash не решается?

Добавлено через 4 минуты
Цитата Сообщение от nezabudka Посмотреть сообщение
команда rm использует для вывода подтверждения
stderr
Не получается осознать происходящее. С первого взгляда создается ощущение, что такое поведение rm только мешает. Есть какая-то польза от вывода вопросов пользователю в stderr?
0
volodin661
2235 / 1020 / 169
Регистрация: 10.12.2013
Сообщений: 3,439
Сегодня, 13:27 15
Цитата Сообщение от IlyaLinux Посмотреть сообщение
Это уже другой язык. Неужели на могучем bash не решается?
а что в нём могучего-то ?
лет 30 назад может и производило впечатление. но не сейчас. нмв.
0
Сегодня, 13:27
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
Сегодня, 13:27

Переименовать файлы по списку в EXCEL
Нужна помощь. Необходимо переименовать несколько файлов. Имеется список файлов например: а.txt...

Простая галерея с возможность загружать файлы и проверкой на имя
Здравствуйте! Задачу, которую пытаюсь решить: создать простейшую галерею с возможность загружать...

Обращение к сгенерированному по ControlTemplate элементу WPF
Есть измененный DataGrid, который строится по вот такому ControlTemplate: &lt;ControlTemplate...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.