如何使用 sed 和 csv 重命名文件

如何使用 sed 和 csv 重命名文件

我是 Linux 新手sedawk但我不介意挑战自己的新想法。话虽这么说,我了解 的目的以及如何使用renamesed来处理常见事件,例如从所有文件中添加$date或删除 a 。_1234但是,我想弄清楚如何重命名 100 个除了文件类型之外彼此没有关系的文件。

重命名示例:

  • 旧名称 alpha.ai 更名为 omega.ai
  • 旧名称pie32.ai更名为apple.ai
  • 旧名称 xmas.ai 更名为 santa.ai

我最初使用 bash 脚本将所有名称提取到 .csv 文件并将它们放置在 A 列中。在 BI 列中写入新名称。现在,由于没有发生常见事件,您如何编写sed或类似的内容来做到这一点?

#!/bin/bash
for i in *.ai
do
        mv $i $(echo $i | sed "a1,b1")

done

答案1

如果您碰巧有一个如下所示的文件:

old_name1, new_name1
old_name2, new_name2
old_name3, new_name3

你可以做一个肮脏的小把戏:

sed 's/^/mv -vi "/;s/, /" "/;s/$/";/' < names.csv | bash -

sed comamnds(以分号分隔)执行此操作(s用于替换,/用作分隔符,任何其他字符都可以,@也经常使用):

  • s/^/mv -vi "/mv -vi "-在每行的开头添加(^是行的开头);
  • s/, /" "/- 将逗号后跟空格替换为" ";
  • s/$/";/- 将双引号附加到所有行($表示行尾)

因此 的输出sed将是这样的:

mv -vi "old_name1" "new_name1"
mv -vi "old_name2" "new_name2"
mv -vi "old_name3" "new_name3"

将被送入bash执行。文件名周围的引号不是强制性的,它们只是保护文件名中任何可能的空格(但是它们肯定不会帮助防止逗号后面的空格,因为它被用作分隔符)。指示显示它正在做什么(如果出现问题,您会知道发生了什么),将导致-v它询问是否要覆盖已经存在的文件。mv-i

答案2

您的脚本中有几个引用问题。它将破坏包含特殊字符的文件名:空格、\[?*-.

**始终在变量替换"$i"和命令替换周围使用双引号"$(sed …)".。如果没有双引号,变量的值将被解释为以空格分隔的通配符模式列表,并且每个模式都由匹配的文件名列表替换(如果没有匹配项,则模式保持不变)。

另外,如果文件名以 开头-,它将被解释为选项 by ,mv也可能被 解释为选项echo。首先传递--告诉命令不会有更多的选项。

for i in *.ai; do
  mv -- "$i" "$(printf '%s\n' "$i" | sed 's,a1,b1,')"
done

(这仍然假设您的文件名不包含换行符。)(我还将参数固定sed为您可能的意思。)


如果文件名列表是简单的逗号分隔且不带引号,则可以使用 shell 脚本对其进行解析。这假设任何文件名中都没有逗号或换行符。

while IFS=, read -r from to junk; do
  mv -- "$from" "$to"
done <"$files_to_rename.csv"

如果您的输入文件是可能引用的 CSV 文件,请使用真正的 CSV 解析器。不要尝试自己推出。看有没有强大的命令行工具来处理 csv 文件?例如,在 Python 中(在标准输入上使用 CSV):

import csv, os, sys
for line in csv.reader(sys.stdin):
    (source, dest) = line
    os.rename(source, dest)

答案3

如果您的文件有有趣的字符('"\$),您可以循环该文件并将其读入 bash 数组。

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

答案4

当遇到这类问题时,我通常会手动使用 sed/bash 技巧。

  1. 我要么编写一个编辑器宏,要么编写一个愚蠢的小程序,读取 csv 文件并写入“mv file1 file2”形式的行。
  2. 然后我运行脚本(或宏)并将输出保存到 run-my-cmds.sh
  3. 目视检查 run-my-cmds.sh 以确保其正确
  4. bash 运行我的cmds.sh

相关内容