Ngành IT ngày nay ngập tràn JSON và YAML, 2 định dạng này ở khắp mọi nơi. Việc sử dụng các CLI tool truyền thống (ví dụ: grep) không hiệu quả khiến người dùng phải tìm kiếm những công cụ mới. Hàng trăm công cụ được sinh ra để truy cập/xử lý dữ liệu từ 1 JSON object, và cộng đồng khá ưa chuộng jq
. Nhưng đây đã phải là lựa chọn tốt nhất để "xem và xử lý" JSON, YAML...? Thử các công cụ này để tìm ra giải pháp xịn nhất.
JMESPath
JMESPath không phổ biến khi xử lý JSON tùy ý, nhưng là cú pháp có sẵn khi dùng aws cli --query
.
JMESPath cũng có câu lệnh cli là jp
https://github.com/jmespath/jp nhưng ít người biết.
Cú pháp JMESPath https://jmespath.org/ trông hơi giống jq
nhưng không phải, và tính năng cũng kém hơn:
aws --region ap-southeast-1 lambda list-functions --query 'Functions[?LastModified > `2023-01-02`].[FunctionName,LastModified]' --output table
-------------------------------------------------
| ListFunctions |
+--------------+--------------------------------+
| myfunction2 | 2023-12-14T13:49:38.000+0000 |
| pymicloud1 | 2023-12-14T16:20:11.000+0000 |
| hntop | 2024-01-08T14:10:58.000+0000 |
+--------------+--------------------------------+
khá kỳ lạ khi phải sử dụng backtick `2023-01-02`
để quote JSON value, nếu dùng "2023-01-02"
sẽ không nhận được gì!
aws cli có 2 kiểu filter: server side và client side. --query
filter từ kết quả đã nhận được từ AWS, trong khi --filter
sẽ filter từ phía API của AWS.
Có vấn đề với cả 2 kiểu filter này:
- server filter: chỉ một số service hỗ trợ option này như ec2, rds, và syntax của mỗi cái cũng khác nhau
- client filter: mỗi lần chỉnh sửa nội dung query là 1 lần gọi tới AWS API. Sau 10 lần chỉnh sửa để viết được query đúng thì mất rất nhiều thời gian.
Kết luận: rất khó dùng hàng ngày, trừ khi viết script cần filter trực tiếp lấy ra 1 vài giá trị. Thay vì dùng aws cli --query, có thể output ra JSON rồi dùng các công cụ sau để xử lý.
aws --region ap-southeast-1 lambda list-functions --output json > functions.json
python với Jupyter notebook
Python hỗ trợ JSON từ stdlib import json
, mọi biến đổi if else for... đều có thể thực hiện bằng cú pháp ngắn gọn.
Khi làm việc với AWS API, import boto3
rồi viết code trên Jupyter notebook là một lựa chọn rất hấp dẫn:
- output được lưu trên Jupyter notebook
- code có thể export ra file python để làm script dùng trong hệ thống
- dễ dàng lấy output của function call này làm input cho function call khác, vì đây là lập trình.
jq
jq
https://jqlang.org/tutorial/ là công cụ phổ biến nhất để xem và xử lý JSON trên CLI.
Nhược điểm: không hỗ trợ YAML.
Hiển nhiên là phải học cú pháp của jq
, điều này là tất yếu vì tất cả các phương án trong bài này đều cần học 1 ngôn ngữ query/lập trình.
Ví dụ sau lấy ra các title có chữ "remote" từ ngày 2025-04-13 trên GitHub API repo awesome-jobs/vietnam
:
curl -o issues.json https://api.github.com/repos/awesome-jobs/vietnam/issues
cat issues.json | jq '.[] | {created_at,title,html_url} | select(.created_at > "2025-04-13" and (.title | ascii_downcase | test("remote")))'
Output:
{
"created_at": "2025-04-16T08:48:11Z",
"title": "[Remote Fulltime] Frontend Software Engineer - $3000 Gross - Basic English communication",
"html_url": "https://github.com/awesome-jobs/vietnam/issues/4676"
}
{
"created_at": "2025-04-14T11:39:43Z",
"title": "[Remote Fulltime] Mobile Tech Lead - $4000 Gross",
"html_url": "https://github.com/awesome-jobs/vietnam/issues/4674"
}
yq
https://github.com/mikefarah/yq
yq
giống như jq
nhưng hỗ trợ cả file YAML.
yq is a portable command-line YAML, JSON, XML, CSV, TOML and properties processor
nên có vẻ như nếu đã dùng jq
thì không có lý do gì để không dùng yq
cả.
Nushell
https://github.com/nushell/nushell
A new type of shell.
Nushell là 1 shell mới hiện đại, tương tự các shell truyền thống bash
, zsh
,... nhưng output/input của mỗi câu lệnh là data có cấu trúc (structured data) thay vì string.
Đừng để bị đánh lừa bởi chữ shell
vì Nushell vừa là shell, vừa là 1 ngôn ngữ lập trình functional. Cũng không cần phải dùng Nushell thay zsh/bash nếu không muốn, hãy coi nó như 1 công cụ xử lý dữ liệu trực tiếp.

Các command trong Nushell được viết lại hoàn toàn (bằng Rust) để hỗ trợ input/output ra các structured data thay vì string.
Bật trên container podman run -it --rm ghcr.io/nushell/nushell
~> ls /etc/ | sort-by modified | take 5
╭───┬──────────────┬──────┬───────┬──────────────╮
│ # │ name │ type │ size │ modified │
├───┼──────────────┼──────┼───────┼──────────────┤
│ 0 │ /etc/fstab │ file │ 89 B │ 3 months ago │
│ 1 │ /etc/group- │ file │ 510 B │ 3 months ago │
│ 2 │ /etc/inittab │ file │ 570 B │ 3 months ago │
│ 3 │ /etc/modules │ file │ 15 B │ 3 months ago │
│ 4 │ /etc/motd │ file │ 284 B │ 3 months ago │
╰───┴──────────────┴──────┴───────┴──────────────╯
Mỗi dòng ở dây là 1 record
(như struct/named tuple/data class).
Output của Nushell thường là 1 bảng, dễ dàng truy cập từng cột (như pandas).
Nushell thậm chí có sẵn http client, không cần tới curl, builtin hỗ trợ JSON, YAML, CSV, sqlite, ... ...
Tài liệu: https://www.nushell.sh/book/
Gửi HTTP GET request, xử lý JSON
http get https://api.github.com/repos/awesome-jobs/vietnam/issues |
select created_at title html_url |
where created_at > '2025-04-13' and ( $it.title | str downcase ) has 'remote' |
upsert created_at { |it| $it.created_at | str substring 0..9} |
to yaml
# output
- created_at: '2025-04-16'
title: '[Remote Fulltime] Frontend Software Engineer - $3000 Gross - Basic English communication'
html_url: https://github.com/awesome-jobs/vietnam/issues/4676
- created_at: '2025-04-14'
title: '[Remote Fulltime] Mobile Tech Lead - $4000 Gross'
html_url: https://github.com/awesome-jobs/vietnam/issues/4674
hay dùng regex:
where created_at > '2025-04-13' and title =~ '(?i)remote'
=~ or like regex match / string contains another
Tính toán, biến đổi map, filter, reduce
Làm bài ProjectEuler 1, ghi ra file pe1:
~> 0..999 | filter {|i| $i mod 3 == 0 or $i mod 5 == 0} | reduce {|x,acc| $acc + $x} | save pe1.txt
~> open pe1.txt
233168
chú ý có dấu space $acc + $x
.
update YAML file
~> cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
~> open pod.yaml | upsert spec.containers.0.image nginx:latest | save pod2.yaml
~> cat pod2.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Nushell rất khác, nên mọi kiến thức về các shell khác không dùng được ở đây, ví dụ save
để ghi ra file chứ không phải >
. Cách set biến environment cũng khác.
https://www.nushell.sh/book/coming_from_bash.html
Ở đây chỉ bàn tới việc dùng nushell để khám phá, biến đổi JSON/YAML.
Nushell còn có tính năng hỗ trợ viết tool CLI rất đơn giản và mạnh mẽ sẽ khám phá vào bài sau.
Kết luận
Thời đại mới cần những công cụ mới. Nushell đã mở lối đi riêng trở thành một công cụ (ít người biết) rất mạnh mẽ cho thời đại AI 4.0.
Hết.
HVN at https://pymi.vn and https://www.familug.org.