【问题标题】:Renaming files in a UNIX directory - shell scripting重命名 UNIX 目录中的文件 - shell 脚本
【发布时间】:2024-04-28 05:30:02
【问题描述】:

我一直在尝试编写一个脚本,它将获取当前工作目录,扫描每个文件并检查它是否是 .txt 文件。然后获取每个文件(即文本文件),并检查其名称中是否包含下划线,是否将下划线更改为连字符。

我知道这是一项艰巨的任务,但这是我目前掌握的粗略代码:

#!/bin/bash
count=1
while((count <= $#))
       do
          case $count in
               "*.txt") sed 's/_/-' $count
          esac
          ((count++))
done

我的想法是,这会将当前工作目录中的文件作为参数并检查每个文件(由 $count 或“count”处的文件表示)。然后对于每个文件,它会检查它是否以 .txt 结尾,如果是,它将使用 sed 将每个下划线更改为连字符。我认为我遇到的主要问题之一是脚本没有从当前工作目录中读取文件。我尝试在运行脚本的命令之后包含目录,但我认为它占用了每一行而不是每个文件(因为每行有 4 个左右的文件)。

无论如何,任何帮助将不胜感激!另外,很抱歉我的代码太糟糕了,我对 UNIX 很陌生。

【问题讨论】:

  • 一个问题是$count 是变量count 的值,它是一个整数。如果你想遍历位置参数,你可以写:for file in "$@"; do ... 或简写for file; do ...

标签: shell unix scripting


【解决方案1】:
for fname in ./*_*.txt; do
  new_fname=$(printf '%s' "$fname" | sed 's,_,-,')
  mv "$fname" "$new_fname"
done

【讨论】:

  • 如果shell是bash,可以写:new_fname=${fname//_/-}
【解决方案2】:

为什么不:

rename 's/_/-/' *.txt

【讨论】:

  • rename: command not found。问题是关于 Unix,而不是特定的 Linux 发行版。但鉴于 Perl 几乎随处可见,它是一个不错且灵活的解决方案。
  • @RolandIllig:我知道rename 并不无处不在,但从shebang 我认为它是在一些现代的类unix 系统上执行的。
【解决方案3】:
$ ls *.txt |同时读取-r文件;回显 $file | grep > /dev/null _ && mv $file $(echo $file | tr _ -);完毕

(未经测试)

【讨论】:

  • 这将在文件名中包含空格的文件上失败。如果你做错了mv,你甚至可能会丢失一些数据。
  • 是的,它会在包含空格的文件上失败。在文件名中添加空格的人应该丢失所有数据。 :)
  • 我有点同意... :-) 但是我们来这里是为了互相了解,这就是我添加此评论的原因。问候。
【解决方案4】:

感谢您的所有投入!总而言之,我认为我找到的最适合我技能水平的解决方案是:

ls *.txt | while read -r file; do echo file |
   mv $file $(echo $file | sed 's,_,-,');
done

这完成了我需要做的事情,而且出于我的目的,我不太担心空间。但是感谢您提出的所有精彩建议,你们都非常聪明!

【讨论】: