2016-08-13 2 views
3

Я хочу удалить n (скажем 2 в нашем случае) самые большие файлы в каталоге.удалить n самых больших файлов в каталоге в терминале ubuntu

files=$(ls -S | head -2) 
rm $files 

Это не работает, потому что имена файлов имеют в них пробелы и всевозможные специальные символы. Я получил аналогичные результаты с этим ls -xS | head -2 | xargs rm. Я думаю, нужно избегать всех специальных символов в имени файла, но есть различные типы специальных символов. Хотя это выполнимо, я не ожидал, что это будет сложно. Я использовал опцию -Q, чтобы указать имена файлов, но я все равно получаю ту же ошибку.

Downloads > files=$(ls -SQ | head -1) 
Downloads > echo $files 
"[ www.UsaBit.com ] - Little Children 2006 720p BRRip x264-PLAYNOW.mp4" 
Downloads > rm $files 
rm: cannot remove ‘"[’: No such file or directory 
rm: cannot remove ‘www.UsaBit.com’: No such file or directory 
rm: cannot remove ‘]’: No such file or directory 
rm: cannot remove ‘-’: No such file or directory 
rm: cannot remove ‘Little’: No such file or directory 
rm: cannot remove ‘Children’: No such file or directory 
rm: cannot remove ‘2006’: No such file or directory 
rm: cannot remove ‘720p’: No such file or directory 
rm: cannot remove ‘BRRip’: No such file or directory 
rm: cannot remove ‘x264-PLAYNOW.mp4"’: No such file or directory 
+0

У них есть цитаты в них? –

+0

к счастью нет! – quantdaddy

+0

Я думал, вы имели в виду, что у меня есть котировки в имени файла. :) – quantdaddy

ответ

2

choroba's answer работает хорошо, и даже несмотря на использование eval бывает безопасна в это случае, это лучше, чтобы сформировать привычку избегать его, если есть альтернативы.
То же самое относится к разбору вывода ls.

В общих рекомендаций являются:

  • Избегайте использование eval на входе вы не контролируете, потому что это может привести к выполнению произвольных команд.

  • Do not parse ls output; если возможно, используйте pathname expansion (globbing).

Тем не менее, иногда ls предлагает так много удобства, что это трудно не использовать его, как это имеет место здесь: ls -S удобно сортирует по размеру файла (в порядке убывания); ручная обработка той же логики была бы нетривиальной.

Цена, которую вы платите за разбор ls вывода, что имена файлов с встроенных переноса строк (\n) не будут обрабатываться правильно (как это имеет место ответа choroba как хорошо). Тем не менее, такие имена файлов редко являются предметом реального беспокойства.

Хотя xargs применяет слово-расщепление его входные линии по умолчанию - именно поэтому обработка имен файлов со встроенным пробельным терпит неудачу - это может быть сделана, чтобы распознать каждую строку ввода, как различны, как есть аргумент (обратите внимание, что ls, когда не выводит на терминал, выводит имя каждого файла на его собственной линии по умолчанию):

GNUxargs (используется на большинстве дистрибутивов Linux):

ls -S | head -2 | xargs -d $'\n' rm  # $'\n' requires bash, ksh, or zsh 

-d $'\n говорит xargs рассматривать каждую строку ввода в целом в качестве отдельного аргумента при передаче аргументов в rm.

BSD/OSXxargs (также работает с GNU xargs):

Это xargs реализация не поддерживает опцию -d, но он поддерживает -0 разделить вклад в аргументы по NULs (0x0 байт). Таким образом, промежуточный tr команда необходима для перевода \n в NULs:

ls -S | head -2 | tr '\n' '\0' | xargs -0 rm 
+0

Это идеальное решение! – quantdaddy

2

Если ls поддерживает опцию -Q, он будет цитировать все имена в двойных кавычках (и обратных косых чертах двойных кавычек).

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

eval rm $(ls -Q | head -2) 

Используйте это с осторожностью! eval опасен, он может запускать данные поворота в код запуска, который вы не можете контролировать. Мои тесты показывают, что ls -Q превращает новую строку в \n, которая не интерпретируется как новая строка в двойных кавычках!

+0

@SurajKeshri: Проверьте обновление. – choroba

+0

Разве это не так опасно ?! –

+0

@ JefréN: Кажется, заменить newline на '\ n', так оно и есть. – choroba

Смежные вопросы