Lệnh awk thú vị hơn mình nghĩ
awk là gì?
awk là lệnh trong bash shell. Nhưng có thể hiểu nó gần giống như một ngôn ngữ thông dịch mạnh mẽ được nhúng sẵn và hộ trợ cực kỳ tốt để xử lý văn bản.
Đã một thời gian dài khi mình phải kiểm tra lỗi cấu trúc trong code của mình và rất tuyệt, nó có một đống lỗi. Nhiều đến hàng nghìn dòng nếu lưu nó ra văn bản để đọc. Lỗi nhiều như thế hoàn toàn là do mình đang phát triển một tính năng mới và trong quá trình nghĩ và code thì mình sẵn sàng code sai một chút rồi sửa dần sau. Miễn là lỗi không quá nhiều. Lượng code mới của mình hiện tại đã lên đến vài nghìn dòng rồi và nó sẽ còn tiếp tục tăng lên trong một thời gian dài nữa.
Thế nhưng việc đọc file báo lỗi trở lại từ công cụ biên dịch thật đáng sợ. Nhiều đến mức khó tả. Mặc dù hầu hết là những lỗi nhỏ thôi nhưng để đọc và sửa cũng tốn thời gian nên mới có cơ hội để mình đọc đến cái lệnh awk này!
Thứ nhất cần có một văn bản có sẵn và ở đây là văn bản build. Gõ lệnh thực hiện việc biên dịch và nó sẽ in cho bạn 1 đống thông báo lỗi từ warning đến error. Và nếu nó dài thì càng tốt.
Sau đó có thể thấy, ngoài những dòng thực sự cần thiết gì thì phần lớn còn lại đều là do cùng một dòng lỗi đầu tiên dẫn đến các dòng tiếp theo bị lỗi. Với việc mình dùng VSCode thì công việc đơn giản chỉ là mở file lỗi lên đọc. Copy cái đường dẫn đến chỗ bị lỗi chẳng hạn như fileHamBiLoi.cpp:54 tức là dòng thứ 54. Nhấn Ctrl+P và dán cái đường dẫn đó vào và nó sẽ tự động nhảy đến đúng file và dòng cần thiết.
Điều hay ho giờ mới nói. Thông thường nếu mở terminal trực tiếp trên vscode thì chỉ cần nhấn vào đường dẫn đó là file sẽ tự link. Điều tương tự cũng xảy ra như khi dùng lệnh grep lấy cả tên files vậy. Nhưng đau đớn thay script build của mình ở một đường dẫn khác nên đường dẫn đến file cần đọc của mình nó kèm với các thư mục đâu đây ấy nên việc link không thể hoạt động bình thường. Mình không thể nhấn trực tiếp vào đường dẫn của thư mục được.
Mà kể cả có vậy thì cũng quá nhiều. Ví dụ:
../../git/hac/mydrive/HacMediaMyDriveVideo.cpp:1884:30: error: 'class HacMediaMyDriveStorage' has no member named 'inProcessingFilesInCategory'
if(mMediaMydriveStorage->inProcessingFilesInCategory(HacMediaMyDriveStorage::Q_eMYDRIVE_CATEGORY_MUSIC)) return; // Not sync while deleting
^
- awk: đây là tên lệnh. Khối lệnh thực thi sau đó sẽ được đặt trong dấu '{}'. Đóng mở ngoặc để giới hạn những câu lệnh tiếp theo sẽ được thực hiện trong khối đó.
- split($0,a,"git/"); là câu lệnh cắt chữ. $0 tức là toàn bộ dòng ban đầu đọc được. Hãy thử dùng awk '{print $0}' để thấy nguyên dòng trước khi bị cắt. ($0 có thể thay bằng $1, $2 với mặc định là được cắt theo dấu cách - hãy thử đi, rất vui đó)
- Sau khi cắt và thử thì mình lấy toàn bộ dữ liệu nằm sau cụm 'git/' nên mới có a[2]. À quên ko nói, a là biến lưu chuỗi sau khi cắt được dùng trong câu lệnh {split($0,a,"git/");. Đương nhiên hoàn toàn có thể thay tên biến là arr hoặc something. Nó chỉ là tên biến thôi. Nhớ là với câu lệnh tiếp theo phải đổi tên đó (arr[2], something[2] phụ thuộc vào biến ban đầu)
- print a[2]; là in chuỗi đó ra ngoài.
Thật tuyệt vời. Mình có toàn bộ những gì mình cần chỉ với lệnh đó.
Có rất nhiều cách để giải quyết vấn đề đó nhưng với bài toán cơ bản là với một văn bản có nhiều nhưng cách thức để đào dữ liệu thực sự đơn giản chỉ cần dùng chút thủ thuật và grep là được thì dùng shell tiện hơn rất nhiều. Nó:
- Nhanh hơn
- Tiện hơn
- Không phải cài thêm phần mềm phụ.
Ngoài lề một chút:
Bài này để lưu lại cái phát hiện thú vị ngày hôm nay của mình với lệnh awk. Mặc dù hầu hết bình thường chủ yếu chỉ được sử dụng để chuẩn bị câu lệnh cho một câu lệnh liên quan trực tiếp với nó là xargs. Ví dụ để xoá một process nào đó đích danh - cái mà bạn ko muốn tìm tên đầy đủ của nó trong hệ điều hành:
ps -aux | grep chro | awk '{print $2}' | xargs kill -9
Rồi là tất cả mọi tiến trình có chữ chro* chẳng hạn như chrome đều biến mất. Không cần phải dò từng tên một để kill và đảm bảo là 'sạch sẽ'. Không phải đọc cái danh sách tiến trình dài đằng đẵng của hệ điều hành.
Nhận xét
Đăng nhận xét