Rustで複数ファイルを一括処理!バッチスクリプト作成手順と実例

Rustで効率的に複数ファイルを一括処理するバッチスクリプトを作成する方法について解説します。日常的なデータ処理やファイル変換作業を自動化することで、作業時間の短縮やヒューマンエラーの削減が可能です。Rustは安全性や高速性に優れており、並列処理も得意なため、大量のファイルを処理するスクリプトに適しています。本記事では、Rustを活用して複数のファイルを一括で処理するバッチスクリプトの作成手順や具体例を紹介し、効率的な自動化を実現する方法を学びます。

目次

Rustでバッチ処理を行うメリット


Rustでバッチ処理を行うことには、いくつかの大きな利点があります。ここでは、Rustがバッチ処理に適している理由を解説します。

安全性の高さ


Rustはコンパイル時にメモリ安全性を保証するため、バッチ処理で大量のファイルやデータを扱う際にも、メモリ関連のバグが発生しにくいです。これにより、不正なメモリアクセスやクラッシュを防ぐことができます。

高速な処理性能


Rustはネイティブコードにコンパイルされるため、実行速度が非常に速いです。大量のファイルを一括処理する際にも、パフォーマンスの低下を最小限に抑えられます。

並列処理が容易


Rustの並行・並列処理をサポートするRayonクレートなどを使用することで、複数のファイルを同時に処理するスクリプトを簡単に作成できます。これにより、処理速度が向上し、効率的にタスクを完了できます。

エラーハンドリングが強力


RustのResult型やOption型を活用することで、エラー処理が堅牢になります。これにより、ファイル処理中に発生する予期しないエラーを適切に処理でき、スクリプトが安定して動作します。

クロスプラットフォーム対応


RustはWindows、Linux、macOSなど、複数のOSで動作するため、作成したバッチスクリプトはさまざまな環境で再利用できます。

Rustのこれらの特徴を活用することで、安全かつ効率的なバッチ処理スクリプトを構築できます。

バッチ処理に必要なRustクレート


Rustでバッチ処理を効率的に行うために役立つクレート(ライブラリ)を紹介します。これらのクレートを使用することで、ファイル操作や並列処理、エラーハンドリングが容易になります。

`std::fs`


Rustの標準ライブラリに含まれるstd::fsモジュールは、ファイル操作に必要な基本的な機能を提供します。ファイルの読み書き、ディレクトリの作成や削除など、シンプルな処理に適しています。

使用例:
“`rust
use std::fs::File;
use std::io::Read;

let mut file = File::open(“example.txt”).expect(“ファイルを開けませんでした”);
let mut contents = String::new();
file.read_to_string(&mut contents).unwrap();

<h3>`walkdir`</h3>  
`walkdir`はディレクトリツリーを再帰的に探索するためのクレートです。大量のファイルを一括で処理する際に便利です。

**インストール方法:**  

toml
[dependencies]
walkdir = “2”

**使用例:**  

rust
use walkdir::WalkDir;

for entry in WalkDir::new(“./data”).into_iter().filter_map(Result::ok) {
println!(“{}”, entry.path().display());
}

<h3>`rayon`</h3>  
`rayon`は並列処理をサポートするクレートで、大量のファイルを同時に処理する際に役立ちます。

**インストール方法:**  

toml
[dependencies]
rayon = “1.5”

**使用例:**  

rust
use rayon::prelude::*;

let files = vec![“file1.txt”, “file2.txt”, “file3.txt”];
files.par_iter().for_each(|file| {
println!(“Processing {}”, file);
});

<h3>`anyhow`</h3>  
`anyhow`はエラー処理をシンプルにするクレートで、バッチ処理中に発生するエラーを容易に扱えます。

**インストール方法:**  

toml
[dependencies]
anyhow = “1.0”

**使用例:**  

rust
use anyhow::{Context, Result};

fn read_file(path: &str) -> Result {
std::fs::read_to_string(path).context(“Failed to read the file”)
}

<h3>`serde` + `serde_json`</h3>  
JSONファイルを扱う場合は、`serde`と`serde_json`が便利です。

**インストール方法:**  

toml
[dependencies]
serde = { version = “1.0”, features = [“derive”] }
serde_json = “1.0”

これらのクレートを活用することで、Rustを使ったバッチ処理のスクリプト作成が効率的になります。
<h2>複数ファイルの一括処理の基本手順</h2>  
Rustで複数ファイルを一括処理するための基本手順を解説します。これらのステップを踏むことで、効率的なバッチスクリプトが作成できます。

<h3>1. 対象ディレクトリの指定</h3>  
最初に、処理したいファイルが保存されているディレクトリを指定します。ディレクトリ内のファイルパスを取得するには、`walkdir`クレートが便利です。

**例:**  

rust
use walkdir::WalkDir;

let dir_path = “./data”;
for entry in WalkDir::new(dir_path).into_iter().filter_map(Result::ok) {
println!(“ファイルパス: {}”, entry.path().display());
}

<h3>2. ファイルのフィルタリング</h3>  
処理するファイルの種類を絞り込むには、拡張子やファイル名でフィルタリングを行います。

**例:**  

rust
for entry in WalkDir::new(dir_path).into_iter().filter_map(Result::ok) {
if entry.path().extension().and_then(|ext| ext.to_str()) == Some(“txt”) {
println!(“処理対象ファイル: {}”, entry.path().display());
}
}

<h3>3. ファイルの読み込みと処理</h3>  
各ファイルを順番に読み込み、必要な処理を施します。

**例:**  

rust
use std::fs;
use std::io::{self, Read};

for entry in WalkDir::new(dir_path).into_iter().filter_map(Result::ok) {
if entry.path().extension().and_then(|ext| ext.to_str()) == Some(“txt”) {
let mut file = fs::File::open(entry.path()).expect(“ファイルを開けませんでした”);
let mut contents = String::new();
file.read_to_string(&mut contents).unwrap();
println!(“内容: {}”, contents);
}
}

<h3>4. 並列処理の活用</h3>  
大量のファイルを効率よく処理するため、`rayon`クレートを使用して並列処理を導入します。

**例:**  

rust
use rayon::prelude::*;

WalkDir::new(dir_path)
.into_iter()
.filter_map(Result::ok)
.filter(|entry| entry.path().extension().and_then(|ext| ext.to_str()) == Some(“txt”))
.par_bridge()
.for_each(|entry| {
let contents = fs::read_to_string(entry.path()).expect(“読み込みエラー”);
println!(“処理中: {}”, entry.path().display());
});

<h3>5. エラーハンドリングの実装</h3>  
ファイル操作中にエラーが発生する可能性があるため、適切なエラーハンドリングを実装します。

**例:**  

rust
use anyhow::{Context, Result};

fn process_file(path: &str) -> Result<()> {
let contents = fs::read_to_string(path).context(“ファイルの読み込み失敗”)?;
println!(“内容: {}”, contents);
Ok(())
}

<h3>まとめ</h3>  
これらのステップに従うことで、Rustを使った効率的なバッチ処理スクリプトを構築できます。ファイル探索、フィルタリング、並列処理、エラーハンドリングを組み合わせることで、堅牢で高速なスクリプトが実現可能です。
<h2>ファイル操作のコード例</h2>  
Rustで複数ファイルを処理する際に役立つ、基本的なファイル読み書きやエラーハンドリングのコード例を紹介します。

<h3>ファイルの読み込み</h3>  
ファイルを読み込んで内容を文字列として取得する方法です。

**例:**  

rust
use std::fs::File;
use std::io::{self, Read};

fn read_file(path: &str) -> io::Result {
let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(contents)
}

fn main() {
let path = “example.txt”;
match read_file(path) {
Ok(contents) => println!(“ファイル内容:\n{}”, contents),
Err(e) => eprintln!(“エラー: {}”, e),
}
}

<h3>ファイルへの書き込み</h3>  
ファイルにデータを書き込む方法です。既存のファイルは上書きされます。

**例:**  

rust
use std::fs::File;
use std::io::{self, Write};

fn write_file(path: &str, data: &str) -> io::Result<()> {
let mut file = File::create(path)?;
file.write_all(data.as_bytes())?;
Ok(())
}

fn main() {
let path = “output.txt”;
if let Err(e) = write_file(path, “こんにちは、Rust!”) {
eprintln!(“エラー: {}”, e);
} else {
println!(“ファイルに書き込みました。”);
}
}

<h3>ファイルの追記</h3>  
既存のファイルにデータを追記する方法です。

**例:**  

rust
use std::fs::OpenOptions;
use std::io::{self, Write};

fn append_to_file(path: &str, data: &str) -> io::Result<()> {
let mut file = OpenOptions::new().append(true).open(path)?;
file.write_all(data.as_bytes())?;
Ok(())
}

fn main() {
let path = “output.txt”;
if let Err(e) = append_to_file(path, “\n追記されたテキスト”) {
eprintln!(“エラー: {}”, e);
} else {
println!(“ファイルに追記しました。”);
}
}

<h3>ディレクトリ内のファイル一覧を取得</h3>  
指定したディレクトリ内のファイルを取得する方法です。`walkdir`クレートを使用すると再帰的な探索も可能です。

**Cargo.tomlに依存関係を追加:**  

toml
[dependencies]
walkdir = “2”

**例:**  

rust
use walkdir::WalkDir;

fn list_files_in_directory(path: &str) {
for entry in WalkDir::new(path).into_iter().filter_map(Result::ok) {
println!(“{}”, entry.path().display());
}
}

fn main() {
let dir_path = “./data”;
list_files_in_directory(dir_path);
}

<h3>エラーハンドリング付きファイル操作</h3>  
`anyhow`クレートを使ってエラーハンドリングをシンプルにする方法です。

**Cargo.tomlに依存関係を追加:**  

toml
[dependencies]
anyhow = “1.0”

**例:**  

rust
use anyhow::{Context, Result};
use std::fs;

fn read_file_with_error_handling(path: &str) -> Result {
fs::read_to_string(path).context(“ファイルの読み込み中にエラーが発生しました”)
}

fn main() -> Result<()> {
let path = “example.txt”;
let contents = read_file_with_error_handling(path)?;
println!(“ファイル内容:\n{}”, contents);
Ok(())
}

<h3>まとめ</h3>  
これらのコード例を活用すれば、Rustでのファイルの読み書きやディレクトリの操作が効率的に行えます。バッチ処理スクリプトを作成する際には、エラーハンドリングを適切に組み込むことで、安定したプログラムを構築できます。
<h2>バッチスクリプト作成の実例</h2>  
ここでは、Rustを使用して複数のCSVファイルを一括で処理するバッチスクリプトの作成例を紹介します。具体的には、CSVファイル内のデータを読み取り、特定の条件に基づいて内容をフィルタリングし、新しいCSVファイルに出力する処理を行います。

<h3>1. 必要なクレートの追加</h3>  
Cargo.tomlに以下の依存関係を追加します。

toml
[dependencies]
csv = “1.1”
walkdir = “2.3”
rayon = “1.5”
anyhow = “1.0”

- **`csv`**:CSVファイルの読み書きに使用  
- **`walkdir`**:ディレクトリ内のファイルを再帰的に探索  
- **`rayon`**:並列処理をサポート  
- **`anyhow`**:エラーハンドリングを簡略化  

<h3>2. バッチ処理スクリプトのコード</h3>  

rust
use anyhow::{Context, Result};
use csv::{ReaderBuilder, WriterBuilder};
use rayon::prelude::*;
use std::fs;
use std::path::Path;
use walkdir::WalkDir;

fn process_csv_file(input_path: &Path, output_dir: &str) -> Result<()> {
// CSVリーダーを作成し、ファイルを開く
let mut reader = ReaderBuilder::new()
.has_headers(true)
.from_path(input_path)
.with_context(|| format!(“Failed to open file: {:?}”, input_path))?;

// 出力ファイルのパスを生成
let output_file_name = format!(
    "{}/filtered_{}",
    output_dir,
    input_path.file_name().unwrap().to_str().unwrap()
);
let mut writer = WriterBuilder::new()
    .has_headers(true)
    .from_path(&output_file_name)
    .with_context(|| format!("Failed to create output file: {}", output_file_name))?;

// レコードをフィルタリングしながら処理
for result in reader.records() {
    let record = result?;
    if let Some(value) = record.get(2) {
        if value == "OK" {
            writer.write_record(&record)?;
        }
    }
}

println!("Processed: {:?}", input_path);
Ok(())

}

fn main() -> Result<()> {
let input_dir = “./input_csv”;
let output_dir = “./output_csv”;

// 出力ディレクトリを作成
fs::create_dir_all(output_dir).context("Failed to create output directory")?;

// ディレクトリ内のCSVファイルを並列処理
WalkDir::new(input_dir)
    .into_iter()
    .filter_map(Result::ok)
    .filter(|entry| entry.path().extension().and_then(|ext| ext.to_str()) == Some("csv"))
    .par_bridge()
    .for_each(|entry| {
        if let Err(e) = process_csv_file(entry.path(), output_dir) {
            eprintln!("Error processing file {:?}: {}", entry.path(), e);
        }
    });

println!("Batch processing completed.");
Ok(())

}

<h3>3. スクリプトの解説</h3>  

1. **`process_csv_file`関数**  
   - CSVファイルを開き、3列目(インデックス2)が"OK"であるレコードのみをフィルタリングして新しいCSVファイルに書き出します。

2. **`main`関数**  
   - 入力ディレクトリ`input_csv`内のCSVファイルを探索し、並列処理で`process_csv_file`関数を呼び出します。  
   - 出力ディレクトリ`output_csv`にフィルタリング後のCSVファイルが保存されます。

<h3>4. 入出力のサンプル</h3>  

**入力CSVファイル (`input_csv/data1.csv`)**  

csv
id,name,status
1,John,OK
2,Alice,FAIL
3,Bob,OK
4,Charlie,FAIL

**出力CSVファイル (`output_csv/filtered_data1.csv`)**  

csv
id,name,status
1,John,OK
3,Bob,OK

<h3>まとめ</h3>  
このバッチスクリプトは、複数のCSVファイルを一括で処理し、条件に合ったデータのみを新しいファイルに出力します。Rustの並列処理を活用することで、大量のファイルを高速に処理できるのが特徴です。
<h2>高速化のための最適化手法</h2>  
Rustでバッチ処理スクリプトを高速化するための最適化手法を紹介します。大量のファイルを効率的に処理するためには、並列処理やメモリ管理の工夫が重要です。

<h3>1. 並列処理の導入</h3>  
Rustの`rayon`クレートを使用して並列処理を導入することで、大量のファイルを同時に処理できます。CPUの複数コアを活用することで処理速度が大幅に向上します。

**例:**  

rust
use rayon::prelude::*;
use std::fs;
use walkdir::WalkDir;

fn process_file(path: &str) {
println!(“Processing: {}”, path);
}

fn main() {
let dir_path = “./data”;

WalkDir::new(dir_path)
    .into_iter()
    .filter_map(Result::ok)
    .filter(|entry| entry.path().is_file())
    .par_bridge()
    .for_each(|entry| {
        process_file(entry.path().to_str().unwrap());
    });

}

<h3>2. バッファリングの活用</h3>  
ファイルの読み書き時にバッファを使用することで、I/O処理の回数を減らし、効率的にデータを処理できます。`BufReader`や`BufWriter`を使うと高速化できます。

**例:**  

rust
use std::fs::File;
use std::io::{BufReader, BufWriter, Write};

fn copy_file_with_buffer(input: &str, output: &str) {
let input_file = File::open(input).expect(“Failed to open input file”);
let output_file = File::create(output).expect(“Failed to create output file”);

let mut reader = BufReader::new(input_file);
let mut writer = BufWriter::new(output_file);

std::io::copy(&mut reader, &mut writer).expect("Failed to copy data");

}

<h3>3. メモリ効率の向上</h3>  
大きなファイルを処理する場合、一度に全データを読み込むとメモリを大量に消費します。ストリーム処理を活用し、少しずつデータを読み込んで処理することで、メモリ使用量を抑えられます。

**例:**  

rust
use csv::ReaderBuilder;
use std::error::Error;

fn process_large_csv(path: &str) -> Result<(), Box> {
let mut rdr = ReaderBuilder::new().from_path(path)?;
for result in rdr.records() {
let record = result?;
println!(“{:?}”, record);
}
Ok(())
}

<h3>4. 不要な処理の回避</h3>  
条件分岐を適切に設定し、必要なファイルのみを処理することで無駄な計算を避けます。ファイルの拡張子や最終更新時刻でフィルタリングするのが効果的です。

**例:**  

rust
use std::fs;
use std::time::SystemTime;

fn should_process_file(path: &str) -> bool {
if let Ok(metadata) = fs::metadata(path) {
if let Ok(modified) = metadata.modified() {
return modified > SystemTime::now() – std::time::Duration::from_secs(86400);
}
}
false
}

<h3>5. コンパイル時の最適化オプション</h3>  
Cargoのリリースビルドで最適化オプションを使用することで、実行速度が向上します。

**ビルドコマンド:**  

bash
cargo build –release

Cargo.tomlに最適化オプションを追加することも可能です。

toml
[profile.release]
opt-level = 3

- **`opt-level = 3`**:最大限の最適化を行います。

<h3>6. 並列処理時のスレッド数調整</h3>  
デフォルトのスレッド数を調整することで、CPUリソースを最大限に活用できます。

**例:**  

rust
rayon::ThreadPoolBuilder::new()
.num_threads(8)
.build_global()
.unwrap();

<h3>まとめ</h3>  
これらの最適化手法を活用することで、Rustのバッチ処理スクリプトは高速かつ効率的になります。並列処理、バッファリング、メモリ管理の工夫により、大量のファイルを効率よく処理できるようになります。
<h2>エラー処理とデバッグの方法</h2>  
Rustでバッチ処理スクリプトを作成する際、エラー処理とデバッグは非常に重要です。適切なエラーハンドリングを行うことで、スクリプトが予期しない状況に対応し、安定した動作を維持できます。ここでは、エラー処理とデバッグの方法について解説します。

<h3>1. 基本的なエラーハンドリング</h3>  
Rustでは、`Result`型や`Option`型を活用してエラーを処理します。`unwrap`や`expect`を使うと簡易的ですが、エラー時にプログラムがパニックする可能性があります。

**例:**  

rust
use std::fs::File;
use std::io::{self, Read};

fn read_file(path: &str) -> io::Result {
let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(contents)
}

fn main() {
match read_file(“example.txt”) {
Ok(contents) => println!(“ファイル内容:\n{}”, contents),
Err(e) => eprintln!(“エラー: {}”, e),
}
}

<h3>2. `anyhow`クレートを使ったエラーハンドリング</h3>  
複雑なエラーハンドリングには`anyhow`クレートが便利です。これを使うと、エラーのチェーンやエラーメッセージにコンテキストを追加できます。

**Cargo.tomlに依存関係を追加:**  

toml
[dependencies]
anyhow = “1.0”

**例:**  

rust
use anyhow::{Context, Result};
use std::fs;

fn read_file(path: &str) -> Result {
fs::read_to_string(path).context(format!(“Failed to read file: {}”, path))
}

fn main() -> Result<()> {
let contents = read_file(“example.txt”)?;
println!(“ファイル内容:\n{}”, contents);
Ok(())
}

<h3>3. エラーをログに記録する</h3>  
エラーをログに記録することで、デバッグや後からの解析が容易になります。`log`と`env_logger`クレートを使うと簡単にログを出力できます。

**Cargo.tomlに依存関係を追加:**  

toml
[dependencies]
log = “0.4”
env_logger = “0.10”

**例:**  

rust
use log::{error, info};
use std::fs::File;

fn open_file(path: &str) {
match File::open(path) {
Ok(_) => info!(“ファイルが正常に開かれました: {}”, path),
Err(e) => error!(“ファイルのオープンに失敗しました: {}, エラー: {}”, path, e),
}
}

fn main() {
env_logger::init();
open_file(“example.txt”);
}

**出力例:**  

ERROR: ファイルのオープンに失敗しました: example.txt, エラー: No such file or directory

<h3>4. デバッグ用マクロ</h3>  
Rustにはデバッグ用マクロ`dbg!`が用意されており、変数や式の値を簡単に確認できます。

**例:**  

rust
fn main() {
let x = 5;
let y = 10;
dbg!(x + y); // => [src/main.rs:4] x + y = 15
}

<h3>5. パニック時のバックトレース表示</h3>  
パニックが発生した際にバックトレースを表示することで、エラーの原因を特定できます。環境変数`RUST_BACKTRACE=1`を設定します。

**例:**  

bash
RUST_BACKTRACE=1 cargo run

<h3>6. コードのテスト</h3>  
バッチ処理の一部をテストすることで、エラーを事前に防げます。Rustの`#[test]`アトリビュートを使って単体テストを書きます。

**例:**  

rust
fn add(a: i32, b: i32) -> i32 {
a + b
}

[cfg(test)]

mod tests {
use super::*;

#[test]
fn test_add() {
    assert_eq!(add(2, 3), 5);
}

}

<h3>まとめ</h3>  
エラーハンドリングとデバッグの方法を適切に組み合わせることで、Rustのバッチ処理スクリプトを堅牢にし、問題発生時にも迅速に原因を特定できます。`anyhow`や`log`クレートを活用し、パニック時のバックトレース表示や単体テストで品質を高めましょう。
<h2>バッチ処理スクリプトの応用例</h2>  
Rustで作成したバッチ処理スクリプトは、さまざまなタスクに応用できます。ここでは、代表的な応用例として、フォーマット変換、ログ処理、データの集計・分析、ファイルのリネーム・整理などを紹介します。

<h3>1. フォーマット変換</h3>  
複数のJSONファイルをCSV形式に変換するバッチスクリプトです。データの変換が必要な場面で活用できます。

**例:**  

rust
use anyhow::Result;
use serde::{Deserialize, Serialize};
use serde_json;
use csv::Writer;
use std::fs;
use walkdir::WalkDir;

[derive(Serialize, Deserialize)]

struct Record {
id: u32,
name: String,
value: f64,
}

fn convert_json_to_csv(input_path: &str, output_path: &str) -> Result<()> {
let data = fs::read_to_string(input_path)?;
let records: Vec = serde_json::from_str(&data)?;

let mut wtr = Writer::from_path(output_path)?;
for record in records {
    wtr.serialize(record)?;
}
wtr.flush()?;
Ok(())

}

fn main() -> Result<()> {
let input_dir = “./json_files”;
let output_dir = “./csv_files”;

fs::create_dir_all(output_dir)?;

for entry in WalkDir::new(input_dir).into_iter().filter_map(Result::ok) {
    if entry.path().extension().and_then(|ext| ext.to_str()) == Some("json") {
        let output_path = format!(
            "{}/{}.csv",
            output_dir,
            entry.path().file_stem().unwrap().to_str().unwrap()
        );
        convert_json_to_csv(entry.path().to_str().unwrap(), &output_path)?;
    }
}
println!("JSON to CSV conversion completed.");
Ok(())

}

<h3>2. ログファイルの処理</h3>  
複数のログファイルを読み取り、エラーメッセージだけを抽出して新しいファイルに保存するスクリプトです。

**例:**  

rust
use std::fs::{self, File};
use std::io::{self, BufRead, BufReader, Write};
use walkdir::WalkDir;

fn extract_errors(input_path: &str, output_path: &str) -> io::Result<()> {
let file = File::open(input_path)?;
let reader = BufReader::new(file);

let mut output_file = File::create(output_path)?;

for line in reader.lines() {
    let line = line?;
    if line.contains("ERROR") {
        writeln!(output_file, "{}", line)?;
    }
}
Ok(())

}

fn main() {
let input_dir = “./logs”;
let output_dir = “./error_logs”;
fs::create_dir_all(output_dir).unwrap();

for entry in WalkDir::new(input_dir).into_iter().filter_map(Result::ok) {
    if entry.path().extension().and_then(|ext| ext.to_str()) == Some("log") {
        let output_path = format!(
            "{}/{}_errors.log",
            output_dir,
            entry.path().file_stem().unwrap().to_str().unwrap()
        );
        if let Err(e) = extract_errors(entry.path().to_str().unwrap(), &output_path) {
            eprintln!("Error processing file {:?}: {}", entry.path(), e);
        }
    }
}
println!("Log error extraction completed.");

}

<h3>3. データの集計・分析</h3>  
複数のCSVファイルからデータを集計し、特定の指標を計算するスクリプトです。

**例:**  

rust
use csv::ReaderBuilder;
use std::error::Error;
use std::fs;
use walkdir::WalkDir;

fn calculate_average(input_path: &str) -> Result> {
let mut rdr = ReaderBuilder::new().from_path(input_path)?;
let mut sum = 0.0;
let mut count = 0;

for result in rdr.records() {
    let record = result?;
    if let Some(value) = record.get(1) {
        sum += value.parse::<f64>()?;
        count += 1;
    }
}
Ok(sum / count as f64)

}

fn main() -> Result<(), Box> {
let input_dir = “./data_csv”;

for entry in WalkDir::new(input_dir).into_iter().filter_map(Result::ok) {
    if entry.path().extension().and_then(|ext| ext.to_str()) == Some("csv") {
        let avg = calculate_average(entry.path().to_str().unwrap())?;
        println!("File: {:?}, Average: {:.2}", entry.path(), avg);
    }
}
Ok(())

}

<h3>4. ファイルのリネーム・整理</h3>  
ファイル名に日付や連番を付けて整理するスクリプトです。

**例:**  

rust
use std::fs;
use std::path::Path;
use walkdir::WalkDir;

fn rename_files(dir: &str) {
for (i, entry) in WalkDir::new(dir).into_iter().filter_map(Result::ok).enumerate() {
if entry.path().is_file() {
let new_name = format!(“file_{:03}.txt”, i + 1);
let new_path = Path::new(dir).join(new_name);
fs::rename(entry.path(), new_path).unwrap();
}
}
}

fn main() {
let dir = “./documents”;
rename_files(dir);
println!(“Files have been renamed.”);
}
“`

まとめ


Rustでバッチ処理スクリプトを作成すると、フォーマット変換、ログ処理、データ集計、ファイル整理など、さまざまなタスクを効率的に自動化できます。これらの応用例を参考に、必要に応じたバッチ処理スクリプトを作成しましょう。

まとめ


本記事では、Rustを使用して複数ファイルを一括処理するバッチスクリプトの作成手順や具体例について解説しました。Rustの特徴である安全性、並列処理の効率性、エラーハンドリングの強力さを活用することで、高速かつ堅牢なバッチ処理が実現できます。

バッチ処理の手順として、ディレクトリ探索、ファイルフィルタリング、ファイル操作、並列処理、エラー処理などの重要なステップを紹介しました。また、フォーマット変換やログ処理、データ集計など、さまざまな応用例も取り上げました。

これらの知識を活用し、日々の業務やデータ処理タスクを効率化し、Rustでの自動化スクリプトの作成に役立ててください。

コメント

コメントする

目次