【问题标题】:Batch Renaming of Files in Linux在 Linux 中批量重命名文件
【发布时间】:2013-12-16 14:01:57
【问题描述】:

我有大约 1000 个文件需要重命名。当前格式为:

exten-B12345678910-C45679891254-D12345645-E4578981-G6546525.1.wav

我想删除 exten--G6546525.1 。文件名的“exten-”部分在所有文件中都相同,但 -G6546525.1 部分在所有文件中不同。是否有脚本可以删除这两个部分并仅保留 B12345678910-C45679891254-D12345645-E4578981.wav 作为文件名?

希望我已经说清楚了。

【问题讨论】:

  • 执行此操作的最佳方法取决于您使用的操作系统。 sed 几乎可以肯定是错误的方法。因此,请告诉我们操作系统,如果是 UNIX,请告诉我们您正在使用的 shell。更新您的标签以匹配。
  • 所有文件都在同一个文件夹中,还是在不同的子文件夹中? -G6546525.1 部分有多“不同”?除了数字值之外,它们是否相同?
  • 首先,非常感谢您的及时回复。
  • 我正在使用 Cent OS,目前在 shell 中,但希望稍后运行 cron,所有文件都在同一个目录中。是的 -G6546525.1 是随机的。我希望可以通过表示最后一个“-”来删除它?
  • 你说你在“shell”中。哪个壳?

标签: linux sed centos rename


【解决方案1】:
for f in "exten-*-G*.wav" ; do
    mv "$f" "$(echo $f | sed 's/exten-\(.*\)-[^-]*\.wav/\1.wav/')"
done

这旨在处理指定的文件格式,并且在出现通配符等情况下可能会失败。

【讨论】:

  • @EdMorton 是的,我同意。 OP 对文件名格式非常具体,所以我确实假设了这个狭窄的定义。
  • 很公平,如果有不明显的警告,那就值得一提。你可以通过适当地引用你的shell变量(即echo "$f"而不是echo $f)和使用printf而不是echo来解决很多问题。
  • 谢谢小伙子,我会全力以赴,让你知道。
【解决方案2】:

以下是如何使用 bash 或 ksh 获取您想要的文件名部分:

$ x="exten-B12345678910-C45679891254-D12345645-E4578981-G6546525.1.wav"
$ echo "$x"
exten-B12345678910-C45679891254-D12345645-E4578981-G6546525.1.wav

$ y="${x#*-}"
$ echo "$y"
B12345678910-C45679891254-D12345645-E4578981-G6546525.1.wav

$ z="${y%-*}"
$ echo "$z"
B12345678910-C45679891254-D12345645-E4578981

澄清如何使用上述重命名文件:

for x in *
do
    y="${x#*-}"
    mv -- "$x" "${y%-*}.wav"
done

请注意,其他 shell 可能有更简单的方法,例如zsh 有一些强大的结构,一些 shell 有一个 rename 命令。

【讨论】:

  • frig,我对快速响应感到不知所措,但我还没有说清楚;这是一个实际的文件名:exten-03333456781-07548994578-20131130-135035-1385819435.41.wav。你可能会认为这是来自 freepbx/asterisk 的录音。我在 B、C、D、E、G 中添加了最初是为了向你们识别文件名的每个部分。请原谅我不识字,可耻的是我在微软领域开始了我的职业生涯:(#
  • @user3052324 你可以使用 Ed 的方法来构造你想要的文件名并使用 shell for 来进行重命名。
  • @user3052324 明白,我更新了我的答案以明确应用程序。
【解决方案3】:

我使用在我的 linux 机器上运行的 PHP 和 phpSecLib2 来完成这种批处理工作。

使用 SecLib,在要重命名文件的 Linux 机器上运行 SSH 连接,然后在文件夹中运行“ls”。然后将文件列表分解成一个 PHP 数组,然后是 for each 循环。

示例代码如下(假设服务器上的文件位置在 /home/user/files/ 并且服务器位置是 localhost):

    <?php

include('Net/SSH2.php');

$ssh = new Net_SSH2('localhost');
if (!$ssh->login('SSHUSER', 'SSHPASS')) {
                exit('Login Failed');
}

$filelist = $ssh->exec("cd /home/user/files;ls");

$filearray = explode("\n", $filelist);

foreach ($filearray as $key) {

    $newarray = explode("-", $key);
    $newfile = $newarray[1] . $newarray[2] . $newarray[3] . $newarray[4] . ".wav";
    $newfile = (string)$newfile;
    $oldfile = (string)$key;

    $rename = "cd /home/user/files;mv '" . $oldfile . "' '" . $newfile . "'";
    $rename = (string)$rename;
    $runrename = $ssh->exec($rename);
}
echo "Done!";
?>

上述代码只需少量更改(用户名/密码和文件夹位置更改)即可工作。

【讨论】:

  • 另外,您可以使用 str.split 在 python 中编写几乎相同的脚本
  • 这似乎违背了传统观念,即您永远不应该尝试解析 ls 的输出(谷歌它),如果我正确理解脚本,它不会在 mv 和所以对通配符和其他字符的各种错误持开放态度。
  • 已修复 - 忘记 (string)$key 并在 mv 部分将 $key 更新为 $oldfile。至于解析ls - 解析ls 和解析ls 的输出是有区别的。我多年来一直通过 PHP 做这件事,没有任何问题。
  • Ed、Mbratch 和 Xarus,你们让我的星期六变得更好了!非常感谢所有人,它现在正在工作。我已经在我的脚本中实现了 Ed 的代码,效果很好。 Ed 请 ping 我你的 paypal;我想捐一点钱。艾登
猜你喜欢
  • 2021-06-17
  • 2016-04-09
  • 1970-01-01
  • 2015-08-15
  • 2015-12-13
  • 2018-11-10
  • 2013-12-19
  • 2013-10-30
相关资源
最近更新 更多