File names with spaces in BASH

前端 未结 7 1331
清酒与你
清酒与你 2020-12-03 07:54

I\'m trying to write script that\'ll crop and resize large photos into HD Wallpapers.

#! /bin/bash


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


        
相关标签:
7条回答
  • 2020-12-03 08:32

    First, you don't need ls. By using ls in backtics, you implicitly make bash parse a string into a list, which splits by whitespaces. Instead, make bash generate the list and separate it without such quirks:

    Also, you need to enclose all $i usages into quotes, to make bash substitute it as a whole, not as a string split to separate words.

    Here's the script that demonstrates both ideas:

    for i in *.jpg ; do 
      echo "$i";
    done
    
    0 讨论(0)
  • 2020-12-03 08:32

    I would recommend to write the for-line like this:

    for i in *.jpg
    

    and encapsulate $i in double-quotes: "$i".


    If you insist on the

    `ls *.jpg`
    

    style, (if you for instance get your file-names from a more complex command) you could try setting IFS to \n:

    IFS='\n'
    

    Compare these two executions:

    $ for f in `ls *`; do echo $f; done
    hello
    world
    test
    
    $ IFS='\n'; for f in `ls *`; do echo $f; done
    hello world
    test
    
    0 讨论(0)
  • 2020-12-03 08:32
     #! /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
    
    0 讨论(0)
  • 2020-12-03 08:41

    Use read to circumvent the problem with spaces. It looks a bit unnatural to write the loop like this but it works better:

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

    with -iname you also get the jpg files that might have an extension with different casing like .JPG. "i" in "iname" means ignore casing.

    0 讨论(0)
  • 2020-12-03 08:41

    In bash, use string replacement with find:

    ${string//substring/replacement}
    Replace all matches of $substring with $replacement.

    so this works:

    find . -type f -name '*.jpg' | while read i ; do /bin/mv -f "$i" ${i// /_}; done
    
    0 讨论(0)
  • 2020-12-03 08:57

    Use double quotes around file names. Like this:

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

    Please note the double quotes around "$i".

    0 讨论(0)
提交回复
热议问题