xargs 是 Linux 文本處理與批次操作的「瑞士軍刀」:它將標準輸入 (或檔案) 轉換為命令列參數,解決「參數列表過長」、「並行執行」、「格式轉換」等經典難題。本文通過 10+ 實戰場景,展示 xargs 的核心參數、組合技巧與避坑指南。
| 參數 | 功能 | 典型用法 |
|---|---|---|
-n N | 每次命令最多帶 N 個參數 | xargs -n 1 cmd 逐行處理 |
-I {} | 替換字串,支援參數在命令中任意位置 | xargs -I {} cp {} /dest/ |
-0 / --null | 以 NUL (\0) 分隔輸入,配合 find -print0 處理含空格/換行檔名 | find . -name "*.log" -print0 | xargs -0 rm |
-P N | 並行執行 N 個進程 (GNU 扩展) | xargs -P 4 -I {} convert {} {}.jpg |
-t | 執行前列印命令 (除錯) | xargs -t rm |
-p | 互動確認每條命令 | xargs -p rm |
-r / --no-run-if-empty | 輸入為空時不執行命令 (GNU 默認行為) | 防誤刪 |
-s SIZE | 命令列最大字元數 (預設 131072) | 避免 Argument list too long |
-d DELIM | 自定義分隔符 (GNU),預設空白/換行 | xargs -d ',' cmd |
# 錯誤:rm *.log → Argument list too long
# 正確:
find /var/log -name "*.log" -type f -print0 | xargs -0 rm -f
# 或分批刪除,每次 100 個
find /var/log -name "*.log" -type f -print0 | xargs -0 -n 100 rm -f
# 將所有 PNG 轉 JPEG,利用 4 核並行
find . -name "*.png" -print0 | xargs -0 -P 4 -I {} convert {} {}.jpg
# 打包當前目錄所有 .c 檔
find . -name "*.c" -print0 | xargs -0 tar -czvf src.tar.gz
# 複製所有 .jpg 到外接盤,保持相對路徑
find . -name "*.jpg" -print0 | xargs -0 -I {} cp --parents {} /mnt/backup/
# 移動大於 100M 的檔案
find . -type f -size +100M -print0 | xargs -0 -I {} mv {} /archive/
# urls.txt 每行一個 URL
cat urls.txt | xargs -n 1 -P 4 wget -c -q
# -n 1 確保每行獨立傳給 wget;-P 4 並行 4 個下載
# 將專案中所有 .java 檔的舊包名替換為新包名
grep -rl "com.old.pkg" --include="*.java" | xargs sed -i 's/com.old.pkg/com.new.pkg/g'
# 找出佔用 8080 端口的 PID 並殺掉
lsof -ti:8080 | xargs -r kill -9
# 清理僵屍進程
ps -eo pid,stat | awk '$2 ~ /Z/ {print $1}' | xargs -r kill -9
find + xargs + grep 精準搜尋# 搜尋包含 "TODO" 的 Python 檔,顯示檔名與行號
find . -name "*.py" -print0 | xargs -0 grep -n "TODO"
# 搜尋最近 7 天修改過的 .conf 檔中的關鍵字
find /etc -name "*.conf" -mtime -7 -print0 | xargs -0 grep "Listen"
# args.txt 每行一個參數
xargs -a args.txt -I {} echo "Processing {}"
find -print0 | xargs -0,否則參數切分錯誤導致誤刪/誤操作。mkdir、mv 目標需為單一):使用 -n 1 或 -I {} 強制逐個執行。xargs 預設不回显,除錯加 -t。xargs 會消耗 stdin,後續命令無法讀取同一流 → 使用 tee 分流或重構管道。flock 同步。| 特性 | xargs | GNU Parallel |
|---|---|---|
| 並行控制 | -P N 基礎支援 | 負載感知、動態調度、進度條、ETA |
| 參數替換 | -I {} 單一佔位符 | {} {.} {/} {//} 豐富模板 |
| 輸入源 | stdin / -a file | stdin / ::: / :::: / --pipe 多樣 |
| 容錯/重試 | 無 | --retry --joblog 完善 |
| 安裝普及度 | 幾乎所有 Linux 內建 | 需額外安裝 |
簡單批次用 xargs,複雜調度/生產級 ETL 用 parallel。
find -print0 | xargs -0 -P N -I {} cmd {} —— 處理海量檔案、並行加速、含特殊字元檔名的標準模板。
熟練掌握 xargs,讓 Shell 腳本從「串行手工」進化為「並行自動化」。