【问题标题】:Adapt file renaming script so that it searches out each file in sub-directories调整文件重命名脚本,以便搜索子目录中的每个文件
【发布时间】:2016-11-30 01:49:07
【问题描述】:

我有一个 .csv 文件,其中看起来像这样:

unnamed_0711-42_p1.mov,day1_0711-42_p1.mov
unnamed_0711-51_p2.mov,day1_0711-51_p2.mov
unnamed_0716-42_p1_2.mov,day1_0716-42_p1_2.mov
unnamed_0716-51_p2_2.mov,day1_0716-51_p2_2.mov

我已编写此代码以将文件从字段 1 中的名称(例如 unnamed_0711-42_p1.mov)重命名为字段 2 中的名称(例如 day1_0711-42_p1.mov)。

csv=/location/rename.csv

cat $csv | while IFS=, read -r -a arr; do mv "${arr[@]}"; done

但是,此脚本仅在它和所有需要重命名的文件位于同一目录时才有效。以前没问题,但现在我需要在各个子目录中查找文件(无需将完整路径添加到我的 .csv 文件中)。

如何调整我的脚本,以便搜索子目录中的文件,然后像以前一样更改名称?

【问题讨论】:

  • 能否重新表述第一行不清楚的内容?
  • 已编辑,希望更清楚。
  • unnamed_0711-42_p1.mov 的位置在哪里。脚本运行的地方是同一个地方吗?
  • 澄清一下,我当前使用的脚本(参见我的代码)与文件位于同一目录中 - 我需要的脚本需要递归搜索,即它与文件(请参阅我的问题的最后一段)

标签: arrays linux bash rename


【解决方案1】:

一个简单的方法来完成这项工作,虽然它会导致一个低效的脚本,是这样的:

for D in `find . -type d`
do
    cat $csv | while IFS=, read -r -a arr; do mv "${arr[@]}"; done
done

这将为当前目录中的每个目录运行您的命令,但这将贯穿每个子目录的整个文件名列表。另一种方法是在处理文件名称时搜索每个文件:

csv=files.csv
while IFS=, read -ra arr; do
    while IFS= read -r -d '' old_file; do
        old_dir=$(dirname "$old_file")
        mv "$old_file" "$old_dir/${arr[1]}"
    done < <(find . -name "${arr[0]}" -print0)
done<"$csv"

这使用find 来定位每个旧文件名,然后使用dirname 来获取旧文件的目录(我们需要它以便mv 不会将重命名的文件放到不同的目录中)。

这将重命名每个文件的每个实例(即,如果 unnamed_0711-42_p1.mov 出现在多个子目录中,每个实例将重命名为 day1_0711-42_p1.mov)。如果您知道每个文件名只会出现一次,您可以通过在 find 命令末尾、管道之前添加 -print -quit 来加快速度。

【讨论】:

  • 这似乎不起作用,只是为了澄清一下,对于“目录名”,我应该输入所有文件所在的顶级/主文件夹(在子目录中)对吗?
  • ./rename.sh: line 7: /DG1440/tester_delete/anotherlevel: 是目录 mv: 无法创建常规文件`/day63_testday2p1_0929-36_p1.mov': 权限被拒绝
  • @bms9nmh 不,“dirname”是一个命令。您应该在我提供的脚本中编辑的唯一内容是您的 csv 文件的名称
  • 好的,对不起,我会试一试,然后回复你。
  • @mona_sax :"$old_dir/${arr[1]} 周围的双引号会注意这里的分词,所以我说这不会处理非标准文件名是正确的。此脚本在我的测试结果确认时有效。虽然我觉得第二个 while 循环是多余的。
【解决方案2】:

下面的脚本

while IFS=, read -ra arr # -r to prevent mangling backslashes
do
 find . -type f -name "${arr[0]}" -printf "mv '%p' '%h/${arr[1]}'" | bash
done<csvfile

应该这样做。


请参阅[ find ] 手册页以了解诸如 %p,%h 之类的 printf 说明符的作用

【讨论】:

  • 嗨,sjjam,这没有用,我收到每个文件的错误“mv: cannot stat `examplefillename.mov': No such file or directory”。我不认为这段代码在递归搜索,它似乎只是在脚本所在的目录中搜索。
  • 这甚至不能正确处理来自.csv 文件的对。在mv 前面添加echo 可以使这一点显而易见。
  • @bms9nmh :我已经更新了我的答案。请看一看。
  • @mona_sax:%p 不考虑非标准文件名,但将其括在单引号中是您为其他答案指出的问题的一种解决方法。请查看编辑。
猜你喜欢
  • 2021-11-27
  • 2021-01-25
  • 1970-01-01
  • 1970-01-01
  • 2015-08-02
  • 2016-11-11
  • 1970-01-01
  • 1970-01-01
  • 2014-06-13
相关资源
最近更新 更多