Qt 批量替换指定文本为目标文本

之前写了一篇《批处理替换指定目录下所有文件夹名和文件名》,但是会存在些小问题,为了优雅的解决问题,打算用Qt开发个应用软件处理一下,同时把存在的问题都解决了。当然前提是目标机允许运行Qt打包的程序。

实现原理很简单,用QFileDialog让用户选择指定目录,通过深度优先搜索(DFS)逐层逐个遍历文件夹和文件,如果名称符合替换条件则替换相应的字符串,需要注意的是搜索时先搜索子文件夹内部再判断文件夹本身。

为了更方便使用,支持用户输入多个字符串,任意一个匹配成功即认为满足替换条件。例如在下图所示的软件界面中的指定文本,支持输入“aa$bb$cc”,如果文件名中带有aa或bb或cc,均视为满足替换条件,会自动替换为目标文本。

软件界面:

 RenameFilesName.h

#ifndef RENAMEFILESNAME_H
#define RENAMEFILESNAME_H

#include <QFileDialog>
#include <QWidget>
#include <QDebug>

#if defined(_MSC_VER)
#pragma execution_character_set("utf-8")
#endif

namespace Ui {
class RenameFilesName;
}

class RenameFilesName : public QWidget
{
    Q_OBJECT

public:
    explicit RenameFilesName(QWidget *parent = 0);
    ~RenameFilesName();

protected:
    void dfsRequireFiles(QString path);     // dfs文件列表
    bool dealIsContainsText(QString name, QString &newName);  // 判断是否包含文本

private slots:
    void on_pushButtonPicDir_clicked();     // 选取目录
    void on_pushButtonSearch_clicked();     // 开始查询

private:
    Ui::RenameFilesName *ui;

    int m_numSuccess;      // 替换成功的数量
    int m_numFailed;       // 替换失败的数量
    int m_totFile;  // 总文件数量
    int m_totDir;   // 总文件夹数量
};

#endif // RENAMEFILESNAME_H

RenameFilesName.cpp

#include "RenameFilesName.h"
#include "ui_RenameFilesName.h"

RenameFilesName::RenameFilesName(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::RenameFilesName)
{
    ui->setupUi(this);
}

RenameFilesName::~RenameFilesName()
{
    delete ui;
}

void RenameFilesName::dfsRequireFiles(QString path)
{
    QDir dir(path);
    QFileInfoList file_list = dir.entryInfoList(QDir::Files | QDir::Hidden | QDir::NoSymLinks);  // 获取文件列表
    QFileInfoList folder_list = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);  // 获取文件夹里列表

    for (int i = 0; i < file_list.size(); i++)
    {
        ++m_totFile;
        QString newName;
        if (dealIsContainsText(file_list.at(i).fileName(), newName))
        {
            QString originPath = file_list.at(i).absoluteFilePath();
            QString newPath = file_list.at(i).absolutePath() + "/" + newName;
            QDir dir(originPath);
            if (dir.rename(originPath, newPath))
            {
                ui->listWidget->addItem(newPath);
                ++m_numSuccess;
            }
            else
                ++m_numFailed;
        }
    }

    for (int i = 0; i != folder_list.size(); i++)
    {
        QString name = folder_list.at(i).absoluteFilePath();
        ++m_totDir;
        dfsRequireFiles(name);  // 递归子目录
        QString newName;
        if (dealIsContainsText(folder_list.at(i).fileName(), newName))
        {
            QString originPath = folder_list.at(i).absoluteFilePath();
            QString newPath = folder_list.at(i).absolutePath() + "/" + newName;
            QDir dir(originPath);
            if (dir.rename(originPath, newPath))
            {
                ui->listWidget->addItem(newPath);
                ++m_numSuccess;
            }
            else
                ++m_numFailed;
        }
    }
}

bool RenameFilesName::dealIsContainsText(QString name, QString &newName)
{
    QStringList listTargetStr = ui->lineEditText->text().split("$");
    for (int i = 0; i < listTargetStr.size(); ++i)
    {
        if (name.contains(listTargetStr.at(i)))
        {
            newName = name.replace(listTargetStr.at(i), ui->lineEditTargetText->text());
            return true;
        }
    }
    return false;
}

void RenameFilesName::on_pushButtonPicDir_clicked()
{
    QString dirName = QFileDialog::getExistingDirectory(this, tr("打开目录"), "",  QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
    ui->lineEditDir->setText(dirName);
}

void RenameFilesName::on_pushButtonSearch_clicked()
{
    ui->labelStatus->setText("查询开始!");
    QString dirName = ui->lineEditDir->text();
    ui->listWidget->clear();
    m_numSuccess = 0;
    m_numFailed = 0;
    m_totDir = 0;
    m_totFile = 0;
    dfsRequireFiles(dirName);
    ui->labelStatus->setText(QString("查询结束!共查询 %1 个子文件夹,%2 个子文件。其中,替换成功的有 %3 条,替换失败的有 %4 条。").arg(m_totDir).arg(m_totFile).arg(m_numSuccess).arg(m_numFailed));
}

实测效果:

在指定目录DisplayImage里,将所有文件名中数字前的前缀统一命名为Image。

分析一下文件名,前缀中不符合规范的命名有image、IMAGE、IME、IMG四种,所以在软件的指定文本中输入image$IMAGE$IME$IMG,目标文本输入Image,点击“开始替换”即可。

修改后效果:

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用Qt框架提供的文件操作函数来实现文本文件的批量替换。下面是一个简单的示例代码,可以帮助你完成这个任务: ```cpp #include <QCoreApplication> #include <QFile> #include <QTextStream> void replaceInFile(const QString& filePath, const QString& searchStr, const QString& replaceStr) { // 打开文件 QFile file(filePath); if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) { qDebug() << "无法打开文件:" << file.errorString(); return; } // 读取文件内容 QTextStream in(&file); QString content = in.readAll(); // 替换文本 content.replace(searchStr, replaceStr); // 将修改后的内容写入文件 file.resize(0); // 清空文件内容 file.seek(0); // 将文件指针重置到文件开头 QTextStream out(&file); out << content; // 关闭文件 file.close(); } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QString searchStr = "要替换文本"; QString replaceStr = "替换后的文本"; QDir dir("文件夹路径"); QStringList filters; filters << "*.txt"; // 只处理扩展名为txt的文件,你可以根据实际需求修改 dir.setNameFilters(filters); QFileInfoList fileList = dir.entryInfoList(); foreach (QFileInfo fileInfo, fileList) { replaceInFile(fileInfo.filePath(), searchStr, replaceStr); } return a.exec(); } ``` 你需要将代码中的 "要替换文本" 替换为你想要替换文本内容,"替换后的文本" 替换为你想要替换成的内容,"文件夹路径" 替换为你的目标文件夹路径。 请确保在使用代码之前备份好你的文件,以防意外情况发生。希望这能帮到你!如有任何问题,请随时向我提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值