基于内容重命名文件

3
在macOS Sierra(版本10.12.6)中,我有一个包含许多纯文本(.txt)文件的目录。每个文件都有一个不太有用的名称,例如“untitled text 252.txt”。我想知道是否可以根据每个文件第一行中的代码对每个文件进行编程重命名。
每个文件都以部分符号(§),一个空格,始终包含一个句点(.)和一个空格的代码开头。代码通常只是数字,但偶尔也会有一个带有字母的尾随连字符(-)。例如:'§ 177.30 ''§ 60.10-a '
我想根据其代码重新命名每个文件,但首先重新格式化代码。简而言之,前缀为P,从代码中去除句点并添加尾随的.txt。使用上述示例,文件名将是:P17730.txtP6010-a.txt
在命令提示符处,我已经找出如何从每个文件中获取代码:
grep -o '^§ [A-Za-z0-9]*\.[A-Za-z0-9\-]* ' *.txt

这将返回从段落符号到尾随空格的所有内容(例如'§ 130.65-a')。
因此,剩下的问题是:
1、如何重新格式化grep结果以得到想要的文件名(例如P13065-a.txt);以及,
2、如何将文件重命名操作与grep组合使用?
2个回答

2

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

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

然后找到所有的*.txt文件,提取数字,并将其重命名为P<数字>.txt。不要直接在原地重命名,最好将文件复制到目标目录并进行重命名:

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

通过执行一段短的脚本:
#!/bin/bash
digits=$(sed -n "1{s/[^0-9]//g;p;}" "$1")
cp "$1" "/path/to/targetdir/$newname"

对于通过find查找到的每个文件(作为第一个位置参数$1给出)。


请复制您的文件并仅在副本上尝试此操作,并确保之后有与之前相同数量的文件,因为有可能两个文件最终具有相同的名称,您将用第二个文件覆盖第一个文件。在进行“mv”操作之前检查目标文件是否存在并拒绝执行“mv”操作可能是一个好主意。 - Mark Setchell
在sed命令上收到错误:'p命令末尾有额外字符'。 - protasm
@vikingfo04,已修复。BSD的sed}之前的p后需要加上分号; - randomir

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

生成一个类似于shell脚本的文件。
mv './file.txt' P6010-a.txt

你可以通过添加| sh来查看并执行它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接