BASH中带空格的文件名

fin*_*ann 13 linux bash

我正在尝试编写脚本来裁剪并将大型照片调整为高清壁纸.

#! /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
Run Code Online (Sandbox Code Playgroud)

但似乎脚本存在文件名有空格的问题(如Tumble Weed.jpg).我怎样才能解决这个问题?

P S*_*ved 22

首先,你不需要ls.通过ls在backtics中使用,您隐式地将bash解析为一个字符串,该列表按空格分割.相反,make bash生成列表并将其分开而没有这样的怪癖:

此外,您需要将所有$i用法括在引号中,以使bash将其替换为整体,而不是将字符串拆分为单独的单词.

这是演示两种想法的脚本:

for i in *.jpg ; do 
  echo "$i";
done
Run Code Online (Sandbox Code Playgroud)

  • 这并不总是有效,因此会产生误导。这总是有效的。`SAVEIFS=$IFS;IFS=$(echo -en "\n\b");for f in $(ls -lah);do echo "$f" 完成;IFS=$SAVEIFS` (2认同)

jde*_*aan 14

使用read来避开空格问题.编写这样的循环看起来有点不自然,但效果更好:

find . -type f -iname "*.jpg" | while read i
do
    # your original code inside the loop using "$i" instead of $i
done
Run Code Online (Sandbox Code Playgroud)

-iname你同时获得可能具有不同外壳的扩展名的jpg文件,如.JPG."in"中的"i"表示忽略套管.


aio*_*obe 5

我建议这样写 for 行:

for i in *.jpg
Run Code Online (Sandbox Code Playgroud)

$i用双引号括起来:"$i".


如果你坚持要

`ls *.jpg`
Run Code Online (Sandbox Code Playgroud)

样式,(例如,如果您从更复杂的命令获取文件名)您可以尝试设置IFS\n

IFS='\n'
Run Code Online (Sandbox Code Playgroud)

比较这两个执行:

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

$ IFS='\n'; for f in `ls *`; do echo $f; done
hello world
test
Run Code Online (Sandbox Code Playgroud)