Как удалить файлы, отфильтрованные awk

Стандартная конструкция для определения функции

run_backup () { … }

В ksh, ударе и zsh, но не в других оболочках, таких как тире, можно определить функцию с

function run_backup { … }

То, что произошло, когда Вы запустили скрипт с тире, было:

  • Оболочка, выполняемая $(run_backup) строка, естественно приводящая к первому сообщению об ошибке с тех пор, не была никакой названной командой run_backup.
  • Оболочка, позже выполненная function run_backup, естественно приводя к второму сообщению об ошибке с тех пор не было никакой названной команды function.
  • Затем оболочка выполнила заключенный в фигурные скобки блок, который самостоятельно является допустимым синтаксисом оболочки.

Обратите внимание, что, поскольку комментарий xenoterracide указывает, так как Вы имеете #!/bin/bash, скрипт был бы запущен bash если Вы не сделали чего-то не так.

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

Еще одна полезная подсказка: когда Вы отлаживаете сценарий оболочки, выполненный bash -x /path/to/script (или sh -x /path/to/script, и т.д.). Это печатает трассировку каждой выполняемой строки. Если Вы хотите проследить просто часть сценария, можно использовать set -x включить трассировки и set +x отключить их. Zsh имеет лучшие трассировки, чем другие, но он имеет несовместимый синтаксис; можно сказать zsh ожидать sh синтаксис с командой emulate sh 2>/dev/null (который не имеет никакого эффекта в других оболочках).

4
22.04.2012, 12:42
3 ответа

У Вас есть две ошибки:

  1. Вы выдерживаете сравнение для размера, который содержит 46; Вы хотите, чтобы это было равно 46.

  2. Вы печатаете всю строку, когда Вы хотите только имя файла.

И дополнительная проблема: какой смысл -ltr к виду ls вывод, когда Вы не используете порядок сортировки?

Вы хотите сделать что-то как

ls -l | awk '$5 == "46" {print $9}' | xargs rm

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

find . -maxdepth 1 -size 46c -delete # requires GNU find

(Выполнение этого портативно является более раздражающим, начиная с POSIX find не имеет -maxdepth или -size это работает в единицах кроме блоков. Лучше записать сценарий в Perl/Python/Ruby/и т.д. это может использовать надлежащее сканирование каталога, которое не войдет в проблему со специальными символами в именах файлов.)

12
27.01.2020, 20:46
  • 1
    Спасибо за Ваш ответ и упоминающий ВСЕ ошибки! Вы абсолютно правы, это хорошо работает теперь. Относительно -ltr, Я предполагаю, что это - просто дурная привычка. –  Eugene S 22.04.2012, 12:53
  • 2
    Также отметьте комментарий выше о парсинге ls вывод, который я позволяю передаче; это - действительно не хорошая идея, из-за возможности пробелов и других специальных символов в именах файлов. –  geekosaur 22.04.2012, 12:56
  • 3
    я знаю это, но я не мог думать о способе избежать этого. Если можно отредактировать ответ и описать способ выполнить эту задачу без использования ls Я буду благодарен. Еще раз спасибо! –  Eugene S 22.04.2012, 13:01
  • 4
    я советовал бы использовать $NF (всегда относящийся к последнему полю) вместо $9. –  jippie 22.04.2012, 13:02
  • 5
    @jippie, это все еще не собирается работать, если существует пробел на имя. –  geekosaur 22.04.2012, 13:03

В zsh, для удаления всех файлов размера 26 в текущем каталоге (первая строка) или текущем каталоге и его подкаталогах (вторая строка), использование L спецификатор шарика:

rm *(L26)
rm **/*(L26)

С GNU или FreeBSD/NetBSD/OSX найдите:

find . -name . -o -type d -prune -o -type f -size 26c -exec rm {} +
find . -type f -size 26c -exec rm {} +

Портативно:

find . -name . -o -type d -prune -o -type f -exec sh -c '[ $(wc -c <"$0") -eq 26 ] && rm -- "$0"' {} \;
find . -type f -exec sh -c '[ $(wc -c <"$0") -eq 26 ] && rm -- "$0"' {} \;
2
27.01.2020, 20:46

find наилучший вариант здесь. можно использовать stat найти размер файла без использования ls

for file in *; do
  (( $(stat -c %s "$file") == 46 )) && rm "$file"
done
0
27.01.2020, 20:46

Теги

Похожие вопросы