Подтвердить что ты не робот

Имена файлов с пробелами в BASH

Я пытаюсь написать script, который обрезает и изменяет размер больших фотографий в HD Wallpapers.

#! /bin/bash


for i in `ls *.jpg`
do
    width=`identify -format '%w' $i`
    height=`identify -format '%h' $i`

    if [ `echo "$width/$height > 16/9" | bc -l` ]
    then
        exec `convert $i -resize 1920 -gravity Center -crop '1920x1080+0+0' +repage temp`
    else
        exec `convert $i -resize x1080 -gravity Center -crop 1920x1080+0+0 +repage temp`
    fi

    rm $i
    mv temp $i
done

Но похоже, что script имеет проблемы с именами файлов, имеющими пробелы (например, Tumble Weed.jpg). Как я могу это исправить?

4b9b3361

Ответ 1

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

Кроме того, вам нужно заключить все $i в кавычки, чтобы сделать bash заменить его как целое, а не как разделение строки для разделения слов.

Здесь script, который демонстрирует обе идеи:

for i in *.jpg ; do 
  echo "$i";
done

Ответ 2

Используйте чтение, чтобы обойти проблему с пробелами. Для написания цикла это выглядит немного неестественно, но он работает лучше:

find . -type f -iname "*.jpg" | while read i
do
    # your original code inside the loop using "$i" instead of $i
done

с -iname вы также получите файлы jpg, которые могут иметь расширение с другим корпусом, например .JPG. "i" в "iname" означает игнорировать корпус.

Ответ 3

Я бы рекомендовал написать строку для строки следующим образом:

for i in *.jpg

и инкапсулируйте $i в двойные кавычки: "$i".


Если вы настаиваете на

`ls *.jpg`

style (если вы, например, получите свои имена файлов из более сложной команды), вы можете попробовать установить IFS на \n:

IFS='\n'

Сравните эти два исполнения:

$ for f in `ls *`; do echo $f; done
hello
world
test

$ IFS='\n'; for f in `ls *`; do echo $f; done
hello world
test

Ответ 4

В bash используйте замену строки с помощью find

${строка//подстрока/замена}

Replace all matches of $substring with $replacement.

так что это работает:

найти. -type f -name '*.jpg' | при чтении i; do/bin/mv -f "$ i" ${i///_}; сделано

Ответ 5

Используйте двойные кавычки вокруг имен файлов. Вот так:

width=`identify -format '%w' "$i"`

Обратите внимание на двойные кавычки вокруг "$i".

Ответ 6

 #! /bin/bash 
 mkfifo ./lsOutput
 ls -1 *.jpg > ./lsOutput
    while read line  
    do 

    width=`identify -format '%w' "$line"` 
    height=`identify -format '%h' "$line"` 

    if [ `echo "$width/$height > 16/9" | bc -l` ] 
    then 
        exec `convert "$line" -resize 1920 -gravity Center -crop '1920x1080+0+0' +repage temp` 
    else 
        exec `convert "$line" -resize x1080 -gravity Center -crop 1920x1080+0+0 +repage temp` 
    fi 

    rm "$line"
    mv temp "$line"
 done<./lsOutput