【问题标题】:Rename file names containing spaces .ksh重命名包含空格的文件名 .ksh
【发布时间】:2019-03-17 15:08:15
【问题描述】:

我正在尝试重命名包含空格的文件。 IFS=$'\n' 实际上作为 FOR 循环现在可以处理那些带有空格的文件名。不幸的是,DIR 中的所有 .csv 文件都插入到变量 FL 中,这会导致错误。有没有办法让变量 FL 一次处理一个文件,同时它还处理文件名中的空格?

脚本:

IFS=$'\n'
for FL in `ls -1 ${DIR}/*.csv`
do
FL_DP=`echo ${FL}`
FL_RN=`echo ${FL_DP} | tr -d '[:blank:]'`
mv ${FL_DP} ${FL_RN}
done

结果:

+ IFS=$\n
+ ls -1 test _1.csv test _2.csv
++ echo test _1.csv
test _2.csv
FL_DP=test _1.csv
test _2.csv
++ echo test _1.csv
test _2.csv
FL_RN=test_1.csv
test_2.csv
+ mv test _1.csv
test _2.csv test_1.csv
test_2.csv
mv: cannot access test _1.csv
test _2.csv

预期结果:

+ ls -1 test _1.csv test _2.csv
++ echo test _1.csv
FL_DP=test _1.csv
++ echo test _1.csv
FL_RN=test_1.csv
mv test _1.csv test_1.csv

【问题讨论】:

  • 添加一个shebang,然后将您的脚本粘贴到那里:shellcheck.net
  • 请不要通过破坏您的帖子为他人增加工作量。通过在 Stack Overflow 上发帖,您已根据 CC BY-SA 3.0 许可授予 Stack Overflow 分发该内容的不可撤销权利。根据 Stack Overflow 政策,任何破坏行为都将被撤销。如果您想了解更多关于删除帖子的信息,请查看How does deleting work?

标签: bash shell unix ksh


【解决方案1】:

您可能只需要用空格引用变量。但是@Cyrus 关于解析 ls 输出有一个很好的观点。虽然很诱人,但它应该被视为人类可读的数据。

如果没有 ls,您可以这样做:

for f in "$dir"/*.csv; do mv -i "$dir/$f" "$dir/${f// /}"; done

【讨论】:

  • 我尝试了您提供的查询,但收到错误消息
  • 它使用 bash 4.4 对我有用。您看到的错误是什么?
  • $dir/${f// /} 错误替换
  • 我认为字符串替换与 ksh 兼容。现在检查
  • 抱歉,我无法重现您的错误。在 ksh 版本(AT&T Research)93u+ 2012-08-01 中它对我来说很好用
【解决方案2】:

在 FL_DP 中从 `backticks` 更改为 "quotes"

不解析ls,直接用for file in dirname..

IFS=$'\n'
for FL in {DIR}/*.csv
do
  FL_DP="${FL}"
  FL_RN=`echo ${FL_DP} | tr -d '[:blank:]'`
  mv ${FL_DP} ${FL_RN}
done

【讨论】:

    【解决方案3】:

    这是一个使用 find、while 和 read 的示例:

    find . -type f | while
      read filename
    do
      echo "$filename"
    done
    

    您可以将上述结构应用于您的特定问题:

    find $DIR -name '*.csv' -type f | while
      read filename
    do
      mv "$filename" ${filename/ /}
    done
    

    【讨论】:

      【解决方案4】:

      你可以找到findawk命令

      find . -name "*.csv" -printf "mv \"%f\" |\"%f\" \n" | awk  -F"|" ' { gsub(" ","",$2); print } '
      

      样品测试

      $ ls -1 *csv
      scores.csv
      'test _1.csv'
      'test _2.csv'
      $ find . -name "*.csv" -printf "mv \"%f\" |\"%f\" \n" | awk  -F"|" ' { gsub(" ","",$2); print } '
      mv "scores.csv"  "scores.csv"
      mv "test _1.csv"  "test_1.csv"
      mv "test _2.csv"  "test_2.csv"
      $
      

      这里 printf 使用 %f 标识符打印文件名,只需添加一个管道并打印文件名 2 次。

      我在这里使用了管道,因为它不会出现在文件名中。现在使用“|”将结果传递给 awk 命令作为分隔符并使用 gsub() 函数替换空格。

      最终结果可以再次传递给 ksh 执行

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 2011-11-20
        • 2014-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-07
        • 2011-07-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多