根据内容重命名文件

Rename file based on content

在 macOS Sierra (v. 10.12.6) 中,我有一个包含许多纯文本 (.txt) 文件的目录。每个文件都有一个无用的名称,例如 "untitled text 252.txt"。我想知道是否可以根据每个文件第一行中的代码以编程方式重命名每个文件。

每个文件都以节符号 (§)、space、始终包含句点 (.) 和 space 的代码开头。代码通常只是数字,但偶尔也会有一个尾随连字符 (-),后跟一个字母。例如:'§ 177.30 ',或'§ 60.10-a '.

我想根据文件的代码重命名每个文件,但首先要重新格式化代码。简而言之,前缀 a P,从代码中删除句点,并添加尾随 .txt。使用上面的示例,文件名将是:P17730.txtP6010-a.txt.

在命令提示符下,我找到了如何从每个文件中获取代码:

grep -o '^§ [A-Za-z0-9]*\.[A-Za-z0-9\-]* ' *.txt

这 returns 从部分符号到尾随白色的所有内容space(例如 '§ 130.65-a ')。

所以,剩下的问题是:

  1. 如何将 grep 结果重新格式化为我想要的文件名(例如 P13065-a.txt);并且,
  2. 如何将文件重命名操作与 grep 结合使用?

您可以使用 sed 仅从第一行提取数字(通过删除所有非数字):

$ sed -n '1 {s/[^0-9]//g; p;}' <<<"§ 177.30 "
17730

然后 find 所有 *.txt 文件,提取数字,并重命名为 P<digits>.txt。不是就地重命名,而是将文件复制到目标目录更安全,即时重命名:

$ mkdir -p /path/to/targetdir
$ find . -name '*.txt' -exec bash -c 'digits=$(sed -n "1{s/[^0-9]//g;p;}" ""); cp "" "/path/to/targetdir/$newname"' _ {} \;

通过执行一个简短的 bash 脚本:

#!/bin/bash
digits=$(sed -n "1{s/[^0-9]//g;p;}" "")
cp "" "/path/to/targetdir/$newname"

对于 find 找到的每个文件(并作为第一个位置参数给出,)。

find . -maxdepth 1 -regex '[^P].*\.txt' -exec \
    sed -n "1 s|§ \([0-9]*\)\.\([0-9a-z-]*\) |mv '{}' P.txt|p" '{}' \
    \;

生成一个 shell 脚本,如

mv './file.txt' P6010-a.txt

您可以通过附加 | sh

查看和执行