24 ポイント 投稿者 GN⁺ 2025-10-23 | 2件のコメント | WhatsAppで共有
  • 10年以上 dotfiles を維持しながら書きためてきたさまざまな shell スクリプトのうち、最もよく使うものを紹介
  • クリップボード・ファイル管理・インターネット・テキスト処理・REPL ランチャー・日付/時刻・AV・プロセス・クイックリファレンス・システム・その他に分かれており、各スクリプトは短いラッパー形式と実践的な例を中心に示される
  • ほとんどのスクリプトは macOS と Linux で動作し、中核となる思想は「既存ツールの面倒な細かさをならす」こと
    • pbcopy/xclip, python3 -m http.server, yt-dlp, ffmpeg, mpv など 標準ユーティリティを統合
  • 特によく使うものとして copy/pasta/pastas/cpwd, mkcd/tempe/trash/mksh, serveit/getsong/getpod/getsubs, scratch/straightquote/markdownquote, timer/boop/tunes など

dotfiles を維持しながら作ってきた、最もよく使うスクリプトの紹介

  • 10年以上にわたって個人の dotfiles を管理しながら作ってきたさまざまな shell スクリプト の中から、よく使うスクリプトを分野別に整理
  • 各スクリプトには目的、使用頻度、代表的な例が添えられており、すぐに応用できるようになっている
  • 共通の目標は 反復作業の短縮プラットフォーム間の抽象化安全性・可読性の向上

クリップボード関連スクリプト

  • copypasta: システムのクリップボードマネージャーを包むラッパーで、macOS の pbcopy や Linux の xclip をベースにしている
    • copy: 出力をクリップボードにコピー
    • pasta: クリップボードからテキストを取得して出力
    • 例: run_some_command | copy, pasta > file.txt, vim "$(pasta)", pasta | base64 --decode
  • pastas: クリップボードの状態が変わるたびに、新しい内容をリアルタイムで出力するツール
    • コピーしたすべてのリンクをファイルに保存したり、複数のリンクをまとめてダウンロードしたりするのに便利
    • 例: pastas > everything_i_copied.txt, pastas | wget -i -
  • cpwd: 現在のディレクトリパスをクリップボードにコピー
    • 複数のターミナルタブ間でディレクトリを移動するときに便利

ファイル管理スクリプト

  • mkcd foo: ディレクトリを作成してすぐ移動 (mkdir foo && cd foo の短縮)
  • tempe: 一時ディレクトリへ移動 (cd "$(mktemp -d)")。サンドボックス環境で一時作業をするときに後片付けが不要
    • 例:
      # Download a file and extract it  
      tempe  
      wget 'https://example.com/big_file.tar.xz'  
      tar -xf big_file.tar.xz  
      # ...do something with the file...  
      
      # Write a quick throwaway script to try something out  
      tempe  
      vim foo.py  
      python3 foo.py  
      
  • trash: ファイルをゴミ箱に移動(macOS/Linux 対応)。単純な rm より誤操作を防ぎやすい
  • mksh: 新しい shell script ファイルを作成し、実行可能に設定して、そのままエディタで開く

インターネット関連スクリプト

  • serveit: ローカルディレクトリで静的ファイルサーバーを起動(デフォルトはポート 8000、Python が未インストールなら代替手段を使用)
  • getsong: yt-dlp で最高音質の音源をダウンロード
  • getpod: 動画をポッドキャスト用の音声として取得するラッパー
  • getsubs: 公式字幕を優先し、自動字幕にフォールバックするロジックで 英語字幕を抽出要約パイプラインやバックアップ用途に向く
  • wifi off/on/toggle: システムの WiFi を制御し、ネットワーク問題の切り分けに使う
  • url: URL 文字列を解析し、プロトコル、ホスト名、パス、クエリ、ハッシュなどを分離・抽出

テキスト加工スクリプト

  • line 10: 標準入力から特定の行を出力(head, tail に近い)
  • scratch: $EDITOR $(mktemp) のように一時テキストバッファを Vim で素早く開くためのもの。使い捨てのメモや小さな変換作業に向く
  • straightquote: スマートクォートを通常のストレートクォートに変換し、コード内の引用符問題を防いでファイルサイズも削減
  • markdownquote: 各行の先頭に > を付けて Markdown の引用文を作成
  • length: 入力文字列の長さを返す(wc -c の代替にもなる)
  • jsonformat: JSON データを整形表示
  • uppered / lowered: 文字列を大文字 / 小文字に変換
  • nato bar: 入力文字列を NATO フォネティックコードに変換(Bravo Alfa Romeo など)
  • u+ 2025: Unicode 文字の名前と記号を調べる
  • snippets foo: 個人用スニペット辞書から特定の短縮文を呼び出す
    • snippet arrow は矢印 →、snippet recruiter は “not interested” のようなテンプレートメッセージ

REPL ランチャー関連

  • Ruby の irb に着想を得て、さまざまな言語の REPL を素早く起動:
    • iclj: Clojure
    • ijs: Deno(なければ Node)
    • iphp: PHP
    • ipy: Python
    • isql: SQLite(Bash でメモリモード)

日付と時刻のスクリプト

  • hoy: 現在の日付を ISO 形式(例: 2020-04-20)で出力し、ファイル名などの接頭辞に使える
  • timer 10m: 時間タイマー(10分など)。完了時に音と OS 通知を送る
  • rn: datecal を使って、現在時刻と月間カレンダーを見やすく表示

オーディオ・ビデオ・画像処理

  • ocr: macOS で画像ファイルからテキストを抽出(今後拡張予定)
  • boop: 直前のコマンドの成功 / 失敗に応じて音で通知(テスト実行後などに直感的で便利)
  • sfx: 特定の効果音ファイル(.ogg)を再生し、booptimer と連携
  • tunes: mpv でオーディオファイルを再生(シャッフル対応)
  • pix: mpv で写真を表示
  • radio: 好みのインターネットラジオ局のクイックランチャー
  • speak: stdin から読んだテキストから Markdown を除去して音声合成(TTS)
  • shrinkvid: ffmpeg で動画ファイルを圧縮
  • removeexif: JPEG から EXIF データを削除。将来的にはさまざまな形式に対応予定
  • tuivid: ターミナル内で動画を視聴。実用頻度は低いがユニークな機能

プロセス管理

  • each: xargs, find ... -exec の代替で、複雑なコマンド実行を簡単にする
  • running foo: 指定キーワードで実行中のプロセス(PID、コマンドなど)を検索し、読みやすい形式で表示
  • murder: kill を包むラッパーで、穏やかなシグナルから強制終了まで段階的に終了。プログラム終了要求時の誤操作防止に役立つ
  • waitfor $PID: 指定した PID が終了するまで待機し、その間スリープしない状態を保つ
  • bb my_command: コマンドを本当のバックグラウンドモードで実行し、デーモンなどの起動に適する
  • prettypath: $PATH を改行付きで見やすく表示(デバッグ時に有用)
  • tryna my_command / trynafail my_command: コマンドが成功するまで繰り返す(run until success)、失敗するまで繰り返す(run until fail)。ネットワークなどさまざまな自動化に応用できる

クイックリファレンスツール

  • emoji: キーワードで emoji を検索して出力
  • httpstatus: すべての HTTP ステータスコード一覧を表示し、特定コードの説明を確認
  • alphabet: 英字アルファベットの小文字・大文字をすべて出力(意外とよく使う)

システム管理

  • theme 0 / theme 1: システム全体のテーマ(ダーク / ライト)を切り替え、Vim や Tmux とも連携
  • sleepybear: システムをスリープモードにする(macOS、Linux)
  • ds-destroy: .DS_Store ファイルを再帰的に削除。macOS ユーザーのフォルダ整理に便利

その他

  • catbin foo: PATH 内のファイルのソースコードをその場で表示
  • notify: OS レベルの通知を送信し、長時間作業の完了をすぐ知らせる
  • uuid: バージョン 4 UUID を生成

結論

  • この記事で紹介されたスクリプトは、筆者が実際によく使っているツール
  • 自作の短縮コマンドスクリプトは 業務効率化、ミス防止、生産性向上 に非常に効果的
  • 皆さんも自分だけの自動化スクリプトを作って活用してみることを勧める

2件のコメント

 
GN⁺ 2025-10-23
Hacker Newsの意見
  • trash a.txt b.png コマンドは a.txtb.png をゴミ箱へ移動するもの。Mac と Linux で使える。以前自分がやっていた方法はファイルごとに順番に処理するので、削除音が各ファイルごとに鳴り、Finder の ⌘Z では最後のファイルしか復元できなかった。改善はできるが、実際には macOS に標準で入っている公式の trash コマンドを使うほうが便利。Finder を使わないので音や ⌘Z での復元はないが、速度も速くて「Put Back」も使える。それと JSON の pretty-print も、node ではなく jq を使えばずっと短いコードで済むし、最近の macOS には jq が最初から入っている。uuid の出力も同様で、v4 UUID が必要なら uuidgen を使うのが無難(man page 参照

    • 自作スクリプトより標準機能を使うほうがよいことは多い。たとえば vim で markdownquote を使う代わりに、ctrl-v で先頭列を選んで i> のあと escape を押すだけでよい。より短く効率的。u+ 2025 がなぜ ñ を返すのか気になるが、実際の Unicode 値は U+00F1。あと catbin foo は cat "$(which foo)" と同じ。zsh を使っているなら cat =foo のほうが短くて強力。zsh では = の後ろで補完が効くので、長いコマンドでも安全に使える。自分は file =firefoxvim =myscript.sh のようによく使う

    • 著者は uuidgen を知らなかったのだろうと推測する。こういう知識や設定を共有すると、いつも自分の盲点が明らかになるのがよい。だから共有は大事

    • Python でも標準で JSON を pretty-print できる

      $ echo '{ "hello": "world" }' | python3 -m json.tool
      {
        "hello": "world"
      }
      
    • trash 情報ありがとう。自分はこれまで tell app \"Finder\" to move {%s} to trash のような AppleScript を使って複数ファイルをゴミ箱に送っていた

    • rm や trash の代替として rip もおすすめ rip プロジェクトリンク

  • 開発者の人生サイクルは本当に面白い。最初はバニラのシェル環境だけを使い、1〜2年目になるとスクリプトや bash alias を何百行も作って使う。15年目になった今は、むしろできるだけ標準のシェルだけを使い、alias も使わず、複雑なことは Python や Go で処理している

    • こういう傾向は、何か悟ったというより単なる怠けから来ている気がする(自分もまったく同じなのでそう言える)。カスタム環境を掘り下げる同僚たちのおかげで新しいツールをよく知ることができ、最近では atuin や fzf のようなツールも Linux に追加した

    • dotfile に alias や function を書いて、よく使うコマンドを記録・記憶する用途に使っている。よく使うツール群を継続的に更新できるし、新しいワークステーションへ移すのも簡単

    • 昔は nix マシンが1台しかなかったので、いろいろカスタマイズしたかった。今は複数台を同時に使うので、必要なパッケージだけ入れて環境を統一している

    • Python で書いたものも今でも script と呼んでいる。script という用語はシェルスクリプトだけに限らないと思う

    • 最近は若いエンジニアたちと働いていて、彼らがいろいろな dotfiles を使っているのを見ると、「自分も昔はああだったな、面倒だったな」と感じる。今ではツールを選択的に使い、必要に応じて柔軟に合わせている。他人のスタイルも尊重している

  • こういう実践的なコツの投稿を HN で見つけるのが本当に好き。ほかの開発者が実際にどう働いているのか、自分が何を学んで取り入れられるのか知りたい。最初は「自分には必要ないだろう」と思っても、ある作業が楽になると、その作業自体が新しいワークフローを生む。だからひとまず試して、合うものだけ残すようにしている。元記事のスタイルも気に入っている。実際の使用頻度も一緒に書かれているのが本当に実用的。自分は簡単な作業ならブラウザの devtools を開いて JavaScript で済ませることが多い。(例: 文字列を小文字に変換するときなど)

  • line スクリプトの代わりに、sed で特定の行を出力するほうが簡単

    sed -n 2p file
    

    これで2行目を出力できる。複数行の出力も

    sed -n 2,4p file
    

    のようにできるので、line スクリプトより有利

    • sed コマンドを複数組み合わせて使うことがよくある。そういうとき、先頭の sed コマンドを毎回変更し続けなければならない。ときには sed の前に grep が必要なこともあるが、cat、tail、head に分ければ各機能をモジュールのように使えてより柔軟になる。それぞれを一つの仕事だけにさせる Unix 哲学にも合っている
  • 自分がよく使う簡単なスクリプトがいくつかある。たとえば:

    #!/usr/bin/env bash
    # ~/bin/,dehex
    
    echo "$1" | xxd -r -p
    
    #!/usr/bin/env bash
    # ~/bin/,ht
    
    highlight() {
      # 色: 30=黒, 31=赤, 32=緑, ...
      escape=$(printf '\033')
      sed "s,$2,${escape}[$1m&${escape}[0m,g"
    }
    
    if [[ $# == 1 ]]; then
      highlight 31 $1
    elif [[ $# == 2 ]]; then
      highlight 31 $1 | highlight 32 $2
    elif [[ $# == 3 ]]; then
      highlight 31 $1 | highlight 32 $2 | highlight 35 $3
    elif [[ $# == 4 ]]; then
      highlight 31 $1 | highlight 32 $2 | highlight 35 $3 | highlight 36 $4
    fi
    

    個人スクリプトは先頭に ,(カンマ)を付けておくと素早く切り替えられる。自分専用スクリプトを履歴から定期的に統計して、もう使わないものを整理する作業には価値があると思う

  • まだ一般化はできていないが、unmv スクリプトでかなり便利に作業している

    #!/bin/sh
    if test "$#" != 2
    then
      echo 'Error: unmv must have exactly 2 arguments'
      exit 1
    fi
    exec mv "$2" "$1"
    
  • いいコツはたくさんあるが、自分は概ね標準ユーティリティ(sed, awk, grep, xargs など)を学んで使っている。理由は、複数のシステムをまたいで作業することが多く、自分の個人スクリプトや alias はたいてい入っていないから。標準ユーティリティでほぼ何でもできる

    • 本当にその通り。どこでも作業できるよう、標準だけを使うようになる。でも本当によくできたツールは、結局は標準インストールになったり apt-get で簡単に入れられるようになったりする。個人スクリプト集より、きちんと管理されたパッケージの形のほうが望ましいと思う
  • 自分がいちばん気に入っている展開用スクリプトを共有する

    # ex - archive extractor
    # 使い方: ex <file>
    function ex() {
      if [ -f $1 ] ; then
      case $1 in
        *.tar.bz2) tar xjf $1 ;;
        *.tar.gz) tar xzf $1 ;;
        *.tar.xz) tar xf $1 ;;
        *.bz2) bunzip2 $1 ;;
        *.rar) unrar x $1 ;;
        *.gz) gunzip $1 ;;
        *.tar) tar xf $1 ;;
        *.tbz2) tar xjf $1 ;;
        *.tgz) tar xzf $1 ;;
        *.zip) unzip $1 ;;
        *.Z) uncompress $1;;
        *.7z) 7z x $1 ;;
        *) echo "'$1' cannot be extracted via ex()" ;;
      esac
      else
        echo "'$1' is not a valid file"
      fi
    }
    
    • これの圧縮する逆 counterpart も作りたい

    • 自分は dtrx を使っているが、自動でフォルダの中に展開してくれるのがよい

    • 自分は aunpack のほうが便利

    • 本当にきれい

    • inotify と systemd の user service まで足せばさらに一段進化しそう。すでにパッケージとして存在する版もある。自作したものは、いわば四角い車輪を作り直している感じ

  • mp4 のエンコードやカットでいつも使う関数が2つある。フラグのおかげで WhatsApp やモバイル版 Discord など、さまざまな環境で互換性を最大化できる

    ffmp4() {
      input_file="$1"
      output_file="${input_file%.*}_sd.mp4"
    
      ffmpeg -i "$input_file" -c:v libx264 -crf 33 -profile:v baseline -level 3.0 -pix_fmt yuv420p -movflags faststart "$output_file"
    
      echo "Compressed video saved as: $output_file"
    }
    
    ffmp4 foo.webm  # foo_sd.mp4に変換
    
    fftime() {
      input_file="$1"
      output_file="${input_file%.*}_cut.mp4"
      ffmpeg -i "$input_file" -c copy -ss "$2" -to "$3" "$output_file"
    
      echo "Cut video saved as: $output_file"
    }
    
    fftime foo.mp4 01:30 01:45  # foo_cut.mp4 を生成
    

    fftime は元動画を再エンコードせずに高速にカットできるが、動画によっては少し問題(再生不能など)が出ることがある。再エンコードするなら -c copy を外せばよい

  • alias や function を作ってテストするたびに ~/.zshrc をすぐ反映したいので、下のような alias を使っている

    alias vz="vim ~/.zshrc && . ~/.zshrc"
    

    そして Mac で docx ファイルを grep するために下の function を使っている

    docgrep() {
      mdfind "\"$@\"" -onlyin /Users/xxxx/Notes 2> >(grep --invert-match ' [UserQueryParser] ' >&2) | grep -v -e '/Inactive/' | sort
    }
    

    さらに、自分の Mac のクリップボードを匿名化して、ChatGPT や社内 Slack などの公開チャネルに貼る前にデバッグ用として下の関数を使っている。実行すると新しく変換されたクリップボードが stdout に表示されるので、見落としがないか確認できる

    anonymizeclipboard() {
      my_user_id=xxxx
      account_ids="1234567890|1234567890" #regex
      corp_words="xxxx|xxxx|xxxx|xxxx|xxxx" #regex
      project_names="xxxx|xxxx|xxxx|xxxx|xxxx" # regex
      pii="xxxx|xxxx|xxxx|xxxx|xxxx|xxxx" # regex
      hostnames="xxxx|xxxx|xxxx|xxxx|xxxx|xxxx|xxxx|xxxx|xxxx" # regex
      pbpaste | sed -E -e 's/([0-9]{1,3})\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/\1.x.x.x/g' \
      -e "s/(${corp_words}|${project_names}|${my_user_id}|${pii}|${hostnames})/xxxx/g" -e "s/(${account_ids})/1234567890/g" | pbcopy
      pbpaste
    }
    alias anon=anonymizeclipboard
    
    • これは本当にいい。こういうことが頻繁にあるのに、適切な方法が見つからず困っていた
 
krepe90 2025-10-24

GeekNewsに掲載されていた Ask GN: よく使うシェルスニペットはありますか? という記事も思い出しますね