сценарий оболочки для удаления файлов не работал

Я хочу удалить повторные изображения, имеющие разрешение меньше затем 228x228. Для этого я записал этот сценарий оболочки:

#!/bin/bash

for i in $( ls ); do
    if [$(identify -format "%w" $i) < 228] && [$(identify -format "%h" $i) < 228];
    then
        rm $i
    fi
done

По некоторым причинам я получил этот вывод, когда я выполняю его:

./del.sh: line 4: [640: command not found
./del.sh: line 4: [550: command not found
./del.sh: line 4: [315: command not found
...

Вы могли сказать мне что случилось в этом сценарии и как зафиксировать его.
Спасибо.

Править: Даже после того, как я добавил пробелы после скобок, я все еще получил ошибку. Это происходило из-за использования < вместо -lt и был зафиксирован. Теперь нет никакой ошибки.

3
задан 11 January 2019 в 12:36

3 ответа

Некоторые проблемы здесь: Во-первых, выражение в a […] протестируйте пробелы потребностей вокруг этого (ловушка № 10), и во-вторых сравнение < не работает с […] тесты (ловушка № 7). Вы любая потребность -lt (меньше, чем) или использование [[…]] вместо этого, который является bashism. Кроме того, for цикл должен быть заменен (ловушка № 1).

Так:

for i in ./*; do
    if [ -e "$i" ]; then
        if [ $(identify -format "%w" "$i") -lt 228 ] && [ $(identify -format "%h" "$i") -lt 228 ];
        then
            rm -- "$i"
        fi
    fi
done

Можно также не хотеть звонить identify дважды получить эти два размера (ловушка № 58), но назвать его только однажды вместо этого и позволить ему распечатать строку, готовую использоваться в качестве переменных присвоений в синтаксисе оболочки.

Если мы пишем

identify -format "width=%w height=%h" "$i"

это распечатает что-то как width=50 heigth=250. Когда мы evaluate, которые представляют в виде строки затем, мы установили две переменные со всего одним вызовом, и условие может быть записано как:

eval "$(identify -format "width=%w height=%h" "$i")"
if [ $width -lt 228 ] && [ $height -lt 228 ];
then
    rm -- "$i"
fi

См. также: общие ловушки удара.

11
ответ дан 17 November 2019 в 09:08

Вместо цикла я использовал бы find с -exec и -delete:

find . -maxdepth 1 -type f  \
   -exec sh -c '
       [ $(identify -format "%w" "$1") -lt 228 ] &&
       [ $(identify -format "%h" "$1") -lt 228 ]' _ {} \; \
   -delete -print

Это также распечатает файлы, которые удалены, можно удалить -print если Вы не хотите это.

6
ответ дан 17 November 2019 в 09:08

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

Существует сценарий оболочки linter назван shellcheck это могло бы захватить некоторые распространенные ошибки в сценариях удара и также избежать некоторых ловушек. Это может быть установлено как любой пакет в человечности-> https://launchpad.net/ubuntu / + source/shellcheck, находится в universe для текущей конюшни.

Это - вывод для Вашего сценария

shellcheck del.sh

In del.sh line 4:
    if [$(identify -format "%w" $i) < 228] && [$(identify -format "%h" $i) < 228];
    ^-- SC1009: The mentioned parser error was in this if expression.
       ^-- SC1073: Couldn't parse this test expression.
        ^-- SC1035: You need a space after the [ and before the ].
                                          ^-- SC1020: You need a space before the ].
                                          ^-- SC1072: Missing space before ]. Fix any mentioned problems and try again.

Если Вы зафиксируете и подадите заявку снова, то Вы получите некоторые другие рекомендации и уже фиксируете упомянутый в принятом ответе.

3
ответ дан 17 November 2019 в 09:08

Другие вопросы по тегам:

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