【问题标题】:Bash Script looping on Find Command: output has spaces查找命令上的 Bash 脚本循环:输出有空格
【发布时间】:2013-03-07 11:26:46
【问题描述】:

我有以下代码,它尝试查找与特定模式匹配的所有文件并将它们复制到新目录,如果文件已存在则添加后缀。这是因为重复的文件名出现在原始列表中 - 因为它们位于不同的目录中。

它按预期工作,除了包含spaces 的文件名,for in loop 将其作为分隔符。

这段代码来自stackoverflow的各个部分,我用过,但不完全理解。

我尝试了各种引用文件名的组合,在某种程度上我只复制了带有空格的文件。

谁能告诉我如何解决这个问题

patterns=( "wom*.gif" "StarB*.gif" "logos*.gif" )
for pattern in "${patterns[@]}"
do
  for fname in $(find $source -name $pattern); 
  do
    echo Path-and-Filename: $fname
    filename=$(basename "$fname")
    extension=${filename##*.}
    filename=${filename%.*}
    echo Just-Filename: $filename.$extension
    suffix=""
    count=0
    while [ -f $dest$filename$suffix.$extension ]
    do
      count=$(($count+1))
      suffix="("$count")"
    done

    cp -v -p "$fname" $dest"$filename"$suffix.$extension >>$dest"CopyImageFiles-"$(date +"%Y-%m-%d").log 2>>$dest"CopyImageFiles-"$(date +"%Y-%m-%d").log
  done
done

【问题讨论】:

    标签: bash find spaces


    【解决方案1】:

    好吧,我使用@ormaaj 的使用while 循环进行阅读的想法让它工作了。我还没有弄清楚它的作用,但我现在已经复制了我所有的文件,这就是我想要的。

    我确信它仍然“脆弱”,我们将不胜感激。

    我没有使用 -print0 因为我不知道如何读取输出的行,它显示为一长行。我假设我需要为每个文件名设置分隔符,但无法弄清楚。现在的大脑很慢。

    patterns=( "*.gif" "*.GIF" "*.tif"  "*.TIF" "*.jpg" "*.JPG" "*.png" "*.PNG")
    for pattern in "${patterns[@]}"
    do
      find "/Volumes/Public/media_pics" -name "$pattern" | while IFS= read -r fname;
        do
          echo Full-Filename: "$fname"
          filename=$(basename "$fname")
          extension=${filename##*.}
          filename=${filename%.*}
          echo Just-Filename: $filename.$extension
          suffix=""
          count=0
          while [ -f $dest$filename$suffix.$extension ]
          do
            count=$(($count+1))
            suffix="("$count")"
          done
    
          cp -v -p "$fname" "$dest$filename$suffix.$extension" >>$dest"CopyImageFiles-"$(date +"%Y-%m-%d").log 2>>$dest"CopyImageFiles-"$(date +"%Y-%m-%d").log
      done
    done
    

    【讨论】:

      【解决方案2】:

      你已经做得很好了。

      for pattern in "${pattern[@]}" 工作正常,空格被保留到pattern 变量中。

      for fname in $(find $source -name $pattern); 坏了。
      请记住,pattern 包含一个空格。
      将其修复为:

      for fname in $(find "$source" -name "$pattern");
      

      在后面的语句中添加引号作为练习 ;-)

      【讨论】:

      • 对不起 - 它看起来没有任何不同,带有空格的文件名在for in loop 空格字符处创建了多个条目。
      • 错了。您不能以这种方式迭代文件名。至少你已经帮助提高了脚本在遇到问题之前不会失败的几率。
      • @mcl 查看有关练习的添加行 ;-)
      • @ormaaj 我阅读了您的参考资料并尝试实现Don't read lines with for,但我显然弄错了,因为在搜索匹配文件后出现了一个模棱两可的重定向错误。我试过while IFS= read -r aline; do echo "$aline" ; done < $(find "/Volumes/Public/media_pics" -name "*.gif")
      • @mcl 你想要一个进程替换<(...)$(...) 是一个命令替换。您可能还想按照关于 find 的说明使用 nul 分隔输出 (-print0)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-26
      • 1970-01-01
      • 1970-01-01
      • 2015-06-17
      • 2011-11-13
      • 1970-01-01
      相关资源
      最近更新 更多