コンテンツにスキップ

スクリプト言語

出典: フリー教科書『ウィキブックス(Wikibooks)』

スクリプト言語は、プログラムのソースコードを直接実行できる特徴を持つプログラミング言語群です。コンパイル不要な即時実行性、高い可読性、柔軟な型システムなどの特徴により、開発効率の向上に大きく貢献します。本稿では、主要なスクリプト言語の特徴と実践的な活用方法を解説します。

Perl

[編集]

強力な正規表現エンジンと、豊富な組み込み関数を持つスクリプト言語です。システム管理やテキスト処理タスクで高い性能を発揮します。

#!/usr/bin/perl
use v5.36; 

# スカラー変数
my $greeting = "Hello, Perl!";
say $greeting;

# 数値演算
my $result = 10 + 3.14;
printf "計算結果: %.2f\n", $result;

# 配列
my @fruits = ('apple', 'banana', 'orange');
say "最初の果物: $fruits[0]";
say "配列の長さ: " . scalar(@fruits);

# 配列操作
push @fruits, 'grape';
my $last_fruit = pop @fruits;
say "取り出した果物: $last_fruit";

# ハッシュ(連想配列)
my %user = (
    name => 'Taro',
    age  => 25,
    city => 'Tokyo'
);
say "名前: $user{name}, 年齢: $user{age}";

# リファレンス
my $fruits_ref = \@fruits;
say "2番目の果物: " . $fruits_ref->[1];

# サブルーチン(関数)定義
sub greet {
    my ($name, $time) = @_;
    return "Good $time, $name!";
}
say greet('Alice', 'morning');

# 正規表現
my $text = "The year is 2024 and the month is 12";
if ($text =~ /year is (\d+)/) {
    say "抽出した年: $1";
}

# ファイル操作
open(my $fh, '>', 'test.txt') or die "ファイルを開けません: $!";
print $fh "これはテストです\n";
close $fh;

# 例外処理
eval {
    die "エラーが発生しました\n";
};
if ($@) {
    say "捕捉したエラー: $@";
}

# リスト処理
my @numbers = (1..5);
my @squared = map { $_ * $_ } @numbers;
say "二乗した数: " . join(', ', @squared);

my @even = grep { $_ % 2 == 0 } @numbers;
say "偶数: " . join(', ', @even);

# 多言語対応
use utf8;
use open ':encoding(utf8)';
my $japanese = "これは日本語です";
say $japanese;

# ここ関数型プログラミング的な機能
my @words = qw(perl is a great language);
my @caps = sort { length($b) <=> length($a) } 
           map { ucfirst $_ } 
           @words;
say "変換後: " . join(' ', @caps);

# オブジェクト指向
package Person;
sub new {
    my ($class, $name) = @_;
    return bless { name => $name }, $class;
}
sub greet {
    my $self = shift;
    say "Hello, I'm " . $self->{name};
}

my $person = Person->new("Bob");
$person->greet();

Ruby

[編集]

Rubyは「プログラマの幸せ」を目的として開発された言語です。オブジェクト指向プログラミングを徹底し、ブロックやメタプログラミングなどの強力な機能を提供します。特にWeb開発フレームワークのRuby on Railsで知られています。

#!/usr/bin/env ruby
# encoding: utf-8

# クラス定義とメソッド定義
class Animal
  # クラスメソッド
  def self.kingdom
    "Animalia"
  end

  # アクセサメソッド
  attr_accessor :name, :age
  
  # コンストラクタ
  def initialize(name, age)
    @name = name
    @age = age
  end
  
  # インスタンスメソッド
  def greet
    "こんにちは、#{@name}です。#{@age}歳です。"
  end
end

# 継承
class Dog < Animal
  # メソッドのオーバーライド
  def greet
    super + "ワンワン!"
  end
end

# モジュールの定義
module Swimmable
  def swim
    "水を泳いでいます"
  end
end

# mix-in
class Fish < Animal
  include Swimmable
end

# ブロックとイテレータ
def repeat_action(times)
  times.times do |i|
    yield i if block_given?
  end
end

# 例外処理
begin
  1 / 0
rescue ZeroDivisionError => e
  puts "エラーが発生しました: #{e.message}"
ensure
  puts "必ず実行される処理"
end

# 配列操作
fruits = %w(apple banana orange)
fruits.map!(&:capitalize)
puts "大文字にした果物: #{fruits.join(', ')}"

# ハッシュ操作
user = {
  name: "太郎",
  age: 25,
  hobbies: ["読書", "旅行"]
}

# シンボル
user[:location] = "東京"

# メタプログラミング
class MyClass
  def method_missing(method_name, *args)
    if method_name.to_s.start_with?('find_by_')
      attribute = method_name.to_s.sub('find_by_', '')
      "#{attribute}で検索中: #{args.first}"
    else
      super
    end
  end
end

# Procとラムダ
greeting = ->(name) { "こんにちは、#{name}さん" }
farewell = Proc.new { |name| "さようなら、#{name}さん" }

# エンumerableモジュールの活用
numbers = (1..10).to_a
even_numbers = numbers.select(&:even?)
squared_numbers = numbers.map { |n| n ** 2 }

# ファイル操作
File.open('test.txt', 'w') do |file|
  file.puts "Rubyのテストファイルです"
end

# 正規表現
text = "私の誕生日は1990年12月31日です"
if text =~ /(\d{4})年(\d{1,2})月(\d{1,2})日/
  puts "年: #{$1}, 月: #{$2}, 日: #{$3}"
end

# ブロック変数のスコープ
sum = 0
[1, 2, 3].each do |n; sum|
  sum = n * 2
  puts "ブロック内のsum: #{sum}"
end
puts "ブロック外のsum: #{sum}"

# 真偽値の扱い
puts "nilとfalse以外は真" if [nil, false, true, 0, "", [], {}].select(&:itself)

# 文字列操作
string = "hello"
puts string * 3
puts string.reverse
puts string.chars.join('-')

# メソッドの戻り値
def demonstrate_return
  return "早期リターン" if true
  "ここは実行されない"
end

# 実行例
dog = Dog.new("ポチ", 3)
fish = Fish.new("ニモ", 1)

puts dog.greet
puts fish.swim
puts Animal.kingdom

repeat_action(3) { |i| puts "アクション#{i + 1}を実行" }

my_class = MyClass.new
puts my_class.find_by_name("太郎")

puts greeting.call("花子")
puts farewell.call("次郎")

puts "偶数: #{even_numbers.join(', ')}"
puts "二乗: #{squared_numbers.join(', ')}"

JavaScript

[編集]

当初はブラウザ上でのみ動作する言語でしたが、Node.jsの登場により、サーバーサイドでも利用可能となりました。非同期処理を前提とした設計と、豊富なエコシステムが特徴です。

// モダンJavaScriptの機能紹介

// 変数宣言とスコープ
let count = 0;
const MAX_COUNT = 10;
var legacyVar = "レガシーな宣言"; // 現代では非推奨

// テンプレートリテラル
const name = "JavaScript";
console.log(`Hello, ${name}!`);

// アロー関数
const add = (a, b) => a + b;
const multiply = (a, b) => {
    console.log('乗算を実行します');
    return a * b;
};

// 分割代入
const person = {
    firstName: "太郎",
    lastName: "山田",
    age: 30
};
const { firstName, lastName } = person;
const numbers = [1, 2, 3, 4, 5];
const [first, second, ...rest] = numbers;

// クラスと継承
class Animal {
    constructor(name) {
        this.name = name;
    }

    speak() {
        return `${this.name}が鳴きます`;
    }

    static getType() {
        return "動物";
    }
}

class Dog extends Animal {
    constructor(name, breed) {
        super(name);
        this.breed = breed;
    }

    speak() {
        return `${super.speak()} - ワンワン!`;
    }
}

// Promise と非同期処理
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));

async function demonstrateAsync() {
    console.log('開始');
    await delay(1000);
    console.log('1秒経過');
    
    try {
        const result = await Promise.all([
            delay(500).then(() => '処理1'),
            delay(800).then(() => '処理2')
        ]);
        console.log('並列処理結果:', result);
    } catch (error) {
        console.error('エラー発生:', error);
    }
}

// イテレータとジェネレータ
function* numberGenerator() {
    yield 1;
    yield 2;
    yield* [3, 4, 5];
}

// MapとSet
const userMap = new Map();
userMap.set('id1', { name: '田中', age: 25 });
userMap.set('id2', { name: '鈴木', age: 30 });

const uniqueNumbers = new Set([1, 1, 2, 2, 3, 3]);

// 配列操作メソッド
const fruits = ['りんご', 'バナナ', 'オレンジ'];
const mappedFruits = fruits.map(fruit => fruit.toUpperCase());
const filteredFruits = fruits.filter(fruit => fruit.length > 3);
const foundFruit = fruits.find(fruit => fruit === 'バナナ');
const sumArray = [1, 2, 3, 4].reduce((acc, curr) => acc + curr, 0);

// オブジェクトの操作
const baseObject = { a: 1, b: 2 };
const newObject = { ...baseObject, c: 3 };
const keys = Object.keys(newObject);
const values = Object.values(newObject);
const entries = Object.entries(newObject);

// モジュールパターン
const Calculator = {
    add: (a, b) => a + b,
    subtract: (a, b) => a - b,
    multiply: (a, b) => a * b,
    divide: (a, b) => b !== 0 ? a / b : null
};

// プロキシの使用
const handler = {
    get: (target, prop) => {
        console.log(`${prop}をアクセス中`);
        return target[prop];
    }
};
const proxyObject = new Proxy({x: 10, y: 20}, handler);

// シンボルの使用
const uniqueKey = Symbol('説明');
const objWithSymbol = {
    [uniqueKey]: '特別な値'
};

// WeakMapとWeakSet
const weakMap = new WeakMap();
const weakSet = new WeakSet();

// 正規表現
const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
const email = "test@example.com";
console.log(emailPattern.test(email));

// エラー処理
class CustomError extends Error {
    constructor(message) {
        super(message);
        this.name = 'CustomError';
    }
}

// 実行例
const demonstrateFeatures = async () => {
    // クラスの使用
    const dog = new Dog('ポチ', '柴犬');
    console.log(dog.speak());
    console.log(Animal.getType());

    // 非同期処理
    await demonstrateAsync();

    // イテレータの使用
    const generator = numberGenerator();
    for (const num of generator) {
        console.log(num);
    }

    // Map/Setの使用
    console.log(userMap.get('id1'));
    console.log(uniqueNumbers.size);

    // プロキシの動作確認
    console.log(proxyObject.x);

    // エラーハンドリング
    try {
        throw new CustomError('カスタムエラーが発生しました');
    } catch (error) {
        console.error(error.name, error.message);
    }
};

// 機能のデモンストレーション実行
demonstrateFeatures().catch(console.error);

// JSON操作
const jsonString = JSON.stringify(person);
const parsedObject = JSON.parse(jsonString);

// Intl APIの使用
const dateFormatter = new Intl.DateTimeFormat('ja-JP', {
    year: 'numeric',
    month: 'long',
    day: 'numeric'
});
console.log(dateFormatter.format(new Date()));

// Optional Chaining
const deepObject = {
    level1: {
        level2: {
            level3: 'value'
        }
    }
};
console.log(deepObject?.level1?.level2?.level3);

// Nullish Coalescing
const value = null;
const defaultValue = value ?? 'デフォルト値';

シェルスクリプト

[編集]

UNIXの思想を体現するスクリプト言語群です。主なシェルには、Bourne Shell (sh)、C SHell, Bash、Zsh、Korn Shell (ksh)などがあります。システムコマンドを組み合わせ、高度な自動化を実現します。

sh
#!/bin/sh
# bshクイックツアー
# POSIXに準拠した移植性の高いシェルスクリプトの例

# 変数定義と代入
MESSAGE="Hello, Bourne Shell!"
CURRENT_DATE=$(date +%Y-%m-%d)

# 基本的な出力
echo "$MESSAGE on $CURRENT_DATE"
echo "Script name: $0"
echo "First argument: $1"
echo "All arguments: $@"
echo "Number of arguments: $#"

# 制御構造:if文
check_number() {
    if [ "$1" -gt 0 ]; then
        echo "$1 は正の数です"
    elif [ "$1" -eq 0 ]; then
        echo "$1 はゼロです"
    else
        echo "$1 は負の数です"
    fi
}

# 制御構造:case文
get_day_type() {
    case "$1" in
        "Mon"|"Tue"|"Wed"|"Thu"|"Fri")
            echo "平日です"
            ;;
        "Sat"|"Sun")
            echo "週末です"
            ;;
        *)
            echo "不正な曜日です"
            ;;
    esac
}

# 制御構造:for文
echo "ファイル一覧:"
for file in *; do
    if [ -f "$file" ]; then
        echo "ファイル: $file"
    elif [ -d "$file" ]; then
        echo "ディレクトリ: $file"
    fi
done

# 制御構造:while文
countdown() {
    local count=$1
    while [ "$count" -gt 0 ]; do
        echo "カウントダウン: $count"
        count=$((count - 1))
        sleep 1
    done
    echo "完了!"
}

# 関数定義と引数の扱い
process_file() {
    if [ $# -ne 1 ]; then
        echo "使用法: process_file ファイル名"
        return 1
    fi

    if [ ! -f "$1" ]; then
        echo "エラー: $1 は通常のファイルではありません"
        return 2
    fi

    echo "ファイル $1 を処理中..."
    cat "$1"
    return 0
}

# 算術演算
calculate() {
    local a=$1
    local b=$2
    echo "加算: $((a + b))"
    echo "減算: $((a - b))"
    echo "乗算: $((a * b))"
    if [ "$b" -ne 0 ]; then
        echo "除算: $((a / b))"
    fi
}

# エラー処理
handle_error() {
    local exit_code=$?
    echo "エラーが発生しました。終了コード: $exit_code"
    exit "$exit_code"
}
trap handle_error ERR

# パイプとリダイレクト
create_test_file() {
    cat > testfile.txt << 'EOL'
これは
テスト用の
ファイルです
EOL
}

process_lines() {
    while IFS= read -r line; do
        echo "行の処理: $line"
    done
}

# 環境変数の操作
show_environment() {
    echo "PATH: $PATH"
    echo "HOME: $HOME"
    echo "USER: $USER"
    echo "SHELL: $SHELL"
}

# ファイルシステム操作
file_operations() {
    local testdir="testdir"
    if [ ! -d "$testdir" ]; then
        mkdir "$testdir"
    fi

    cd "$testdir" || exit
    touch "testfile.txt"
    echo "テストデータ" > "testfile.txt"
    ls -l
    cd ..
    rm -rf "$testdir"
}

# コマンド終了ステータスのチェック
check_command() {
    if command -v "$1" > /dev/null 2>&1; then
        echo "$1 コマンドは利用可能です"
        return 0
    else
        echo "$1 コマンドは見つかりません"
        return 1
    fi
}

# メイン処理
main() {
    echo "=== bshクイックツアー開始 ==="
    
    check_number 5
    check_number 0
    check_number -3
    
    get_day_type "Mon"
    get_day_type "Sun"
    
    countdown 3
    
    create_test_file
    process_file "testfile.txt"
    
    calculate 10 5
    
    show_environment
    
    file_operations
    
    check_command "ls"
    check_command "nonexistentcommand"
    
    echo "=== テスト終了 ==="
}

# スクリプトの実行
main "$@"
csh
#!/bin/csh
# C Shell クイックツアー
# C言語に似た文法を持つシェルスクリプトの例

# 変数設定
set message = "Hello, C Shell!"
set count = 1
set numbers = (1 2 3 4 5)
set today = `date +%Y-%m-%d`

# 環境変数の設定
setenv CUSTOM_VAR "custom value"

# 配列の操作
set fruits = (apple banana orange)
echo "First fruit: $fruits[1]"      # C Shellは1から始まるインデックス
echo "All fruits: $fruits"
echo "Number of fruits: $#fruits"

# エイリアスの定義
alias ll 'ls -l'
alias greet 'echo "Hello, \!^"'

# 制御構造:if-then-else
if ($count < 5) then
    echo "countは5未満です"
else if ($count == 5) then
    echo "countは5です"
else
    echo "countは5より大きいです"
endif

# 制御構造:switch-case
switch ($TERM)
    case "xterm*":
        echo "xtermターミナルです"
        breaksw
    case "vt100":
        echo "VT100ターミナルです"
        breaksw
    default:
        echo "その他のターミナルです"
        breaksw
endsw

# 制御構造:foreach
foreach num ($numbers)
    echo "Number: $num"
end

# 制御構造:while
set counter = 1
while ($counter <= 3)
    echo "Counter: $counter"
    @ counter++
end

# 算術演算
@ result = 10 + 5
@ square = 5 ** 2
echo "10 + 5 = $result"
echo "5の2乗 = $square"

# 関数定義(C Shellではラベルとgotoを使用)
start:
    echo "関数のような処理の開始"
    if ($?argv) then
        echo "引数: $argv"
    endif
    goto continue

continue:
    echo "処理の続き"
    goto end

# ファイル操作
if (! -d "testdir") then
    mkdir testdir
endif

cd testdir
touch testfile.txt
echo "テストデータ" > testfile.txt

# ファイルテスト演算子
if (-f "testfile.txt") then
    echo "testfile.txtは通常のファイルです"
endif

if (-x "/bin/ls") then
    echo "/bin/lsは実行可能です"
endif

# 入力の処理
echo -n "お名前を入力してください: "
set name = $<
echo "こんにちは、$name さん"

# パイプとフィルタ
cat testfile.txt | grep "テスト"

# ヒアドキュメント(C Shellの方式)
cat << 'EOT' > config.txt
設定ファイル
項目1: 値1
項目2: 値2
EOT

# 配列の操作と文字列処理
set words = (The quick brown fox)
echo "単語数: $#words"
echo "最後の単語: $words[$#words]"

# 正規表現によるパターンマッチング
if ("hello" =~ "h.*o") then
    echo "パターンにマッチしました"
endif

# エラーハンドリング
onintr cleanup
    echo "割り込みを検知しました"

cleanup:
    cd ..
    rm -rf testdir
    echo "クリーンアップ完了"

# 特殊変数の使用
echo "スクリプト名: $0"
echo "現在のシェル: $shell"
echo "ホームディレクトリ: $home"

# 終了処理
end:
    echo "スクリプトを終了します"
    exit 0
ksh
#!/bin/ksh

# 変数の定義
name="KornShell"
version="93u+"

# 関数の定義
greet_user() {
  echo "Hello, $1! Welcome to $name version $version."
}

# 配列の使用例
fruits=("apple" "banana" "cherry")
echo "Fruits array: ${fruits[@]}"

# ループの使用例
echo "Loop through fruits array:"
for fruit in "${fruits[@]}"; do
  echo "Fruit: $fruit"
done

# 条件分岐
echo "Check if version is 93u+:"
if [[ $version == "93u+" ]]; then
  echo "You're using the latest version!"
else
  echo "Please update your KornShell."
fi

# コマンド置換の例
current_date=$(date)
echo "Current date and time: $current_date"

# パイプとリダイレクトの例
echo "Listing files in current directory:"
ls | sort > sorted_files.txt

# 退出ステータスの使用
exit_status=$?
echo "The last command exit status: $exit_status"

# 引数を使ったスクリプトの実行
if [[ $# -gt 0 ]]; then
  echo "Arguments passed to script: $@"
else
  echo "No arguments passed."
fi

# 無限ループと中断
count=0
while true; do
  count=$((count + 1))
  if [[ $count -ge 5 ]]; then
    echo "Breaking the loop after $count iterations."
    break
  fi
done
bash
#!/bin/bash

# 変数の定義
name="Bash"
version="5.1"

# 関数の定義
greet_user() {
  echo "Hello, $1! Welcome to $name version $version."
}

# 配列の使用例
fruits=("apple" "banana" "cherry")
echo "Fruits array: ${fruits[@]}"

# ループの使用例
echo "Loop through fruits array:"
for fruit in "${fruits[@]}"; do
  echo "Fruit: $fruit"
done

# 条件分岐
echo "Check if version is 5.1:"
if [[ $version == "5.1" ]]; then
  echo "You're using the latest version!"
else
  echo "Please update your Bash."
fi

# コマンド置換の例
current_date=$(date)
echo "Current date and time: $current_date"

# パイプとリダイレクトの例
echo "Listing files in current directory:"
ls | sort > sorted_files.txt

# 退出ステータスの使用
exit_status=$?
echo "The last command exit status: $exit_status"

# 引数を使ったスクリプトの実行
if [[ $# -gt 0 ]]; then
  echo "Arguments passed to script: $@"
else
  echo "No arguments passed."
fi

# 無限ループと中断
count=0
while true; do
  count=$((count + 1))
  if [[ $count -ge 5 ]]; then
    echo "Breaking the loop after $count iterations."
    break
  fi
done
zsh
#!/bin/zsh

# 変数の定義
name="Zsh"
version="5.9"

# 関数の定義
greet_user() {
  echo "Hello, $1! Welcome to $name version $version."
}

# 配列の使用例
fruits=("apple" "banana" "cherry")
echo "Fruits array: ${fruits[@]}"

# ループの使用例
echo "Loop through fruits array:"
for fruit in "${fruits[@]}"; do
  echo "Fruit: $fruit"
done

# 条件分岐
echo "Check if version is 5.9:"
if [[ $version == "5.9" ]]; then
  echo "You're using the latest version!"
else
  echo "Please update your Zsh."
fi

# コマンド置換の例
current_date=$(date)
echo "Current date and time: $current_date"

# パイプとリダイレクトの例
echo "Listing files in current directory:"
ls | sort > sorted_files.txt

# 退出ステータスの使用
exit_status=$?
echo "The last command exit status: $exit_status"

# 引数を使ったスクリプトの実行
if [[ $# -gt 0 ]]; then
  echo "Arguments passed to script: $@"
else
  echo "No arguments passed."
fi

# 無限ループと中断
count=0
while true; do
  count=$((count + 1))
  if [[ $count -ge 5 ]]; then
    echo "Breaking the loop after $count iterations."
    break
  fi
done

Python

[編集]

Pythonは「読みやすさ」を重視して設計されたスクリプト言語です。インデントによるブロック構造や豊富な組み込み型により、直感的なコーディングが可能です。科学技術計算、機械学習、Web開発など、幅広い分野で活用されています。

#!/usr/bin/env python3

# 変数の定義
name = "Python"
version = "3.10"

# 関数の定義
def greet_user(username):
    print(f"Hello, {username}! Welcome to {name} version {version}.")

# 配列(リスト)の使用例
fruits = ["apple", "banana", "cherry"]
print("Fruits list:", fruits)

# ループの使用例
print("Loop through fruits list:")
for fruit in fruits:
    print(f"Fruit: {fruit}")

# 条件分岐
print("Check if version is 3.10:")
if version == "3.10":
    print("You're using the latest version!")
else:
    print("Please update your Python.")

# コマンド置換(現在の日時を取得)
import datetime
current_date = datetime.datetime.now()
print(f"Current date and time: {current_date}")

# パイプとリダイレクト(ファイルに書き込む)
with open("sorted_fruits.txt", "w") as file:
    sorted_fruits = sorted(fruits)
    file.write("\n".join(sorted_fruits))

# 退出ステータスの使用
exit_status = 0  # Pythonでは明示的にexitすることも可能ですが、通常はプログラムの終了でステータスコードが返されます
print(f"The exit status is: {exit_status}")

# 引数を使ったスクリプトの実行
import sys
if len(sys.argv) > 1:
    print(f"Arguments passed to script: {sys.argv[1:]}")
else:
    print("No arguments passed.")

# 無限ループと中断
count = 0
while True:
    count += 1
    if count >= 5:
        print(f"Breaking the loop after {count} iterations.")
        break
    1. まとめ

スクリプト言語は、その即時実行性と高い生産性により、現代のソフトウェア開発において重要な位置を占めています。各言語には独自の強みがあり、用途に応じて適切な選択をすることで、効率的な開発が可能となります。特に自動化やプロトタイピング、データ分析などの分野では、スクリプト言語の特徴を活かした開発が有効です。