Ed text editor


Ed text editor là một line text editor, là một text editor rất là lâu đời. Hầu như hiện nay người dùng bình thường ít ai biết tới. Ed là dạng line text editor, xử lý theo dạng từng dòng lệnh. Theo mình thấy cũng rất thú vị. Trong một số tình huống cần chỉnh sửa số lượng file lớn cùng 1 lúc thì ed rất hữu dụng mà các text editor khác không thể làm được hoặc làm được nhưng cũng phức tạp. Ta cùng tìm hiểu text editor đã bị lãng quên này nhé. ed text editor hầu như có mặt sẳn trên các distro linux, ta không cần phải cài gì hết. Nhưng mình sài bản Arco Linux chưa được cài ed nên ta cài bằng câu lệnh sau.
sudo pacman -S ed

Bây giờ ta thử tạo file và thêm nội dung vào file nhé.

[~]$ mkdir ed          <-- tạo  thư mục ed       
[~]$ cd ed         <-- di chuyển vào thư mục ed
[~/ed]$ ed text.txt   <-- tạo file text.txt
text.txt: No such file or directory
P   <-- P là lệnh show comand promt, dấu nhắc lệnh , default là ký hiệu *
*a   <-- a là append , chuyển qua chế độ thêm text vào text.txt
Welcome to ed line text editor.     <-- nội dung cần thêm
.       <-- kết thúc nội dung thêm bằng dấu '.'
*,pn  <-- in ra file dùng ',pn'  p nghĩa là print , n nghĩa là in ra số dòng.  
1	Welcome to ed line text editor.    <-- ta thấy in ra nội dung.
*w    <-- Nội dung được lưu trên buffer, w: sẽ lưu từ buffer xuống file.
32  <-- lưu được 32 bytes.
*q  <-- thoát
[~/ed]$ cat text.txt  <-- ta có thể xem lại file bằng cat  
Welcome to ed line text editor.
[~/ed]$ 

Ngoài ra ta cũng có thể vừa save vừa thoát bằng câu lệnh "wq". Ta có thể mở file text.txt lại và chỉnh lại default prompt.

[~/ed]$ ed -p '#' text.txt
32
#,pn
1	Welcome to ed line text editor.
#q
[~/ed]$ 

Nếu ta gỏ những lệnh không có thì sẽ báo lỗi ta dùng H command để nhận thông báo lỗi rõ ràng hơn.

[~/ed]$ ed -p '#' text.txt
32
#abc  <-- không có lệnh abc
?    <-- báo lỗi là dấu ?
#H   <-- gõ H sẽ thấy thông báo lỗi dễ hiểu hơn.
Invalid command suffix
#q
[~/ed]$ 

Nếu ta thêm text vào file nhưng ta muốn thoát không lưu thì ta gõ q 2 lần.

[~/ed]$ ed -p '#' text.txt
32
#,   <-- in ra  file text.txt
Welcome to ed line text editor.
#a  <-- thêm 
This is store in buffer.
.  <-- kết thúc thêm
#,pn  <-- in có số dòng
1	Welcome to ed line text editor.
2	This is store in buffer.
#,p  <-- in không có số dòng
Welcome to ed line text editor.
This is store in buffer.
#q  <-- q không save buffer
?
#q  <-- thoát
[~/ed]$ 

Hoặc ta dùng 'Q' để không save buffer và thoát luôn.

[~/ed]$ ed -p '#' text.txt
32
#,pn
1	Welcome to ed line text editor.
#a
This text is store in buffer.
.
#,pn
1	Welcome to ed line text editor.
2	This text is store in buffer.
#Q
[~/ed]$ cat text.txt 
Welcome to ed line text editor.
[~/ed]$ 

Ví dụ để xóa dòng thứ 3 ta dùng '3d'.

[~/ed]$ ed -p '#' text.txt
57
#,pn
1	Welcome to ed line text editor.
2	Second line.
3	Third line.
#3d 
#,pn
1	Welcome to ed line text editor.
2	Second line.
#w
45
#q
[~/ed]$ cat text.txt
Welcome to ed line text editor.
Second line.
[~/ed]$ 

Để thay đổi 1 dòng ta dùng 'c'. Ví dụ thay đổi dòng 1 ta gõ '1c'.

[~/ed]$ ed -p '#' text.txt
45
#,pn
1	Welcome to ed line text editor.
2	Second line.
#1c     <-- change dòng 1
Change first line.
.   <-- kết thúc change.
#,pn
1	Change first line.
2	Second line.
#w
32
#q
[~/ed]$ cat text.txt 
Change first line.
Second line.
[~/ed]$

Nếu ta muốn thêm 1 nội dung vào dòng 2 thì sao ? Ta sẽ di chuyển tới dòng 2 và gõ 'i'.

[~/ed]$ ed -p '#' text.txt
32
#,pn
1	Change first line.
2	Second line.
#2  <-- di chuyển xuống dòng  2
Second line.
#i   <-- insert tại dòng 2
insert second line.
.   <-- kết thúc insert
#,pn
1	Change first line.
2	insert second line.
3	Second line.
#w
52
#q
[~/ed]$ 

Nếu ta muốn copy 1 dòng và paste vào cuối file.

[~/ed]$ ed -p '#' text.txt
52
#,pn
1	Change first line.
2	insert second line.
3	Second line.
#2t$   <--- copy dòng 2 vào cuối buffer.
#,pn
1	Change first line.
2	insert second line.
3	Second line.
4	insert second line.
#w
72
#q
[~/ed]$

2 dòng 2, t là copy, $ là cuối buffer.

Để di chuyển con trỏ lên xuống các dòng trong file, ta chỉ cần gõ số hàng là đi đến được dòng đó. Ví dụ di chuyển tới dòng 3, ta chỉ việc gõ 3.

[~/ed]$ ed -p '#' text.txt
72
#,pn
1	Change first line.
2	insert second line.
3	Second line.
4	insert second line.
#$    <-- khi load file thi hiện tại con trỏ dòng cuối
insert second line.
#=  <-- = là xem số dòng cuối buffer
4
#.=  <-- .= là xem số dòng hiện tại của con trỏ
4
#1  <-- chuyển dòng 1
Change first line.
#=  <-- dòng cuối buffer là dòng 4.
4
#.=  <-- hiện tại con trỏ ở dòng 1.
1
#+  <-- + là di chuyển xuống 1 dòng.
insert second line.
#.=  <-- hiện tại dòng 2
2
#-   <-- - là di chuyển lên 1 dòng.
Change first line.
#.=   <-- hiện tại ở dòng 1.
1
#q
[~/ed]$ 

  • : là di chuyển xuống 1 dòng. +3 là di chuyển xuống 3 dòng.
  • : là di chuyển lên 1 dòng. -2 là di chuyển lên 2 dòng. Để in ra toàn buffer ta dùng ',pn'. Nếu ta muốn in ra buffer từ dòng hiện tại đến cuối thì ta dùng ';pn'.
[~/ed]$ ed -p '#' text.txt
72
#,pn
1	Change first line.
2	insert second line.
3	Second line.
4	insert second line.
#2   <-- di chuyển dòng 2.
insert second line.
#;pn  <-- in ra từ dòng 2 đến cuối buffer.
2	insert second line.
3	Second line.
4	insert second line.
#q
[~/ed]$ 

Nếu muốn copy, xóa, di chuyển nhiều dòng cùng 1 lúc thì sao?

Ví dụ copy dòng 2,3 vào dòng 1, ta gõ '2,3t1'. Ví dụ move dòng 2,3,4,5 vào dòng 2, ta gõ '2,5m2'.

m là move, t là copy

Ta xem ví dụ sau, copy dòng 2,3 vào dòng đầu, ta gõ '2,3t0'.

[~/ed]$ ed -p '#' text.txt
72
#,pn
1	Change first line.
2	insert second line.
3	Second line.
4	insert second line.
#2,3t0
#,pn
1	insert second line.
2	Second line.
3	Change first line.
4	insert second line.
5	Second line.
6	insert second line.
#q
?
#q
[~/ed]$

Ta thử xem ví dụ tiếp theo di chuyển dòng 1,2 xuống dòng cuối, ta gõ '1,2m$'.

[~/ed]$ ed -p '#' text.txt
72
#,pn
1	Change first line.
2	insert second line.
3	Second line.
4	insert second line.
#1,2m$
#,pn
1	Second line.
2	insert second line.
3	Change first line.
4	insert second line.
#q
?
#q
[~/ed]$ 

Delete 2 dòng cuối.

[~/ed]$ ed -p '#' text.txt
72
#,pn
1	Change first line.
2	insert second line.
3	Second line.
4	insert second line.
#3,4d
#,pn
1	Change first line.
2	insert second line.
#

Để xóa tất cả ta dùng '1,$d'.

Ta có thể load thêm file vào file đang mở, giống như copy từ file khác vào file hiện tại. Ta dùng command 'r tên file'

[~/ed]$ cat file1.txt   <-- ta có file1
hello from file1.txt
[~/ed]$ cat file2.txt   <-- ta có file2
hello from file2.txt
[~/ed]$ cat text.txt    <-- file hiện tại
Change first line.
insert second line.
Second line.
insert second line.
[~/ed]$ ed -p '#' text.txt  <-- mở file
72
#,pn
1	Change first line.
2	insert second line.
3	Second line.
4	insert second line.
#r file1.txt  <-- load file 1 vào buffer
21
#,pn
1	Change first line.
2	insert second line.
3	Second line.
4	insert second line.
5	hello from file1.txt    <-- file1 đã được thêm vào cưới buffer.
#1      <-- di chuyển dòng 1
Change first line.
#r file2.txt  <-- load file2 vào buffer thì file2 vẫn được thêm vào cuối buffer.
21
#,pn
1	Change first line.
2	insert second line.
3	Second line.
4	insert second line.
5	hello from file1.txt
6	hello from file2.txt
#wq 
114
[~/ed]$

Nếu muốn load file1.txt vào đầu file text.txt ta dùng '0r file1.txt'.

[~/ed]$ ed -p '#' text.txt             
114
#,pn
1	Change first line.
2	insert second line.
3	Second line.
4	insert second line.
5	hello from file1.txt
6	hello from file3.txt
#0r file1.txt
21
#,pn
1	hello from file1.txt
2	Change first line.
3	insert second line.
4	Second line.
5	insert second line.
6	hello from file1.txt
7	hello from file3.txt
#

Nếu ta muốn copy dòng 1, dòng 2, dòng 3 của file text.txt ra file mới. Ta gõ như sau '1,3w newfile.txt'.

[~/ed]$ ed -p '#' text.txt
114
#,pn
1	Change first line.
2	insert second line.
3	Second line.
4	insert second line.
5	hello from file1.txt
6	hello from file3.txt
#1,3w newfile.txt  <-- copy dòng 1,2,3 ra file newfile.txt
52
#q
[~/ed]$ ls
file1.txt  file2.txt  newfile.txt  text.txt

[~/ed]$ cat newfile.txt 
Change first line.
insert second line.
Second line.

[~/ed]$ cat text.txt   
Change first line.
insert second line.
Second line.
insert second line.
hello from file1.txt
hello from file3.txt
[~/ed]$ 

Ta đang mở file này, giờ muốn chuyển sang file khác. Ta dùng 'e newfile.txt'.

[~/ed]$ ed -p '#' text.txt
114
#,pn
1	Change first line.
2	insert second line.
3	Second line.
4	insert second line.
5	hello from file1.txt
6	hello from file3.txt
#e newfile.txt	--> chuyển sang file mới.
52
#,pn
1	Change first line.
2	insert second line.
3	Second line.
#

Nếu chuyển sang file mới mà chưa lưu buffer trên file củ thì ed sẽ cảnh báo.

[~/ed]$ ed -p '#' file1.txt
21
#,pn
1	hello from file1.txt
#a   <-- thêm nội dung mới
new message.
.
#,pn
1	hello from file1.txt
2	new message. 
#e file2.txt   <-- chuyển sang file mới
?   
#H           
Warning: buffer modified <-- cảnh báo chưa lưu buffer xuống file file1.txt
#w       <-- lưu xuống file1.txt
34
#e file2.txt <-- mở file2.txt
21
#,pn
1	hello from file3.txt
#q
[~/ed]$ 

Nếu buffer chưa lưu mà mở file mới, ed sẽ cảnh báo, nếu ta không muốn lưu và chuyển file mới luôn thì dùng 'E file moi'.

[~/ed]$ ed -p '#' file1.txt
34
#,pn
1	hello from file1.txt
2	new message.
#a
not save message
.
#,pn
1	hello from file1.txt
2	new message.
3	not save message
#E file2.txt
21
#,pn
1	hello from file3.txt
#q
[~/ed]$ 

Đặt tên cho file dùng 'f tên file'.

[~/ed]$ ed                 
f texting.txt
texting.txt
P
*a
Default text.        
.
*,pn
1	Default text.
*wq
14
[~/ed]$ cat texting.txt 
Default text.
[~/ed]$ 

Hoặc ta thêm nội dung xong rồi lưu ra file 'w tên file'.

[~/ed]$ ed 
P
*a
Hello new file.
.
*,pn
1	Hello new file.
*w  
?
*w file3.txt <-- lưu file
16
*q
[~/ed]$ cat file3.txt  
Hello new file.
[~/ed]

Để scroll trong ed ta có những cách sau.

1 di chuyển dòng 1. mỗi lần enter sẽ hiện 1 dòng.
z sẽ scroll từng trang tùy kích thướt cửa terminal ta mở nhỏ lớn.
1,10z sẽ scroll từ dòng 1 đến dòng 10.
,n : sẽ in ra từ  đâu đến cuối.

Còn nếu muốn nối 2 dòng lại thành 1 thì dung 'j'. ví dụ 1,2j sẽ nối dòng 1 và 2 với nhau.

[~/ed]$ ed -p '#' text.txt         
114
#,pn
1	Change first line.
2	insert second line.
3	Second line.
4	insert second line.
5	hello from file1.txt
6	hello from file3.txt
#1,2j
#,pn
1	Change first line.insert second line.
2	Second line.
3	insert second line.
4	hello from file1.txt
5	hello from file3.txt
#

Nếu ta muốn đánh dấu hàng nào đó, sau đó ta sẽ quay lại vị trí đó sau thì ta dùng bookmark. Ta tạo bookmark bằng kx : tạo book mark x, gọi bookmark x ta gõ 'x.

[~/ed]$ ed -p '#' text.txt
114
#,pn
1	Change first line.
2	insert second line.
3	Second line.
4	insert second line.
5	hello from file1.txt
6	hello from file3.txt
#1
Change first line.
#kx   <-- tạo bookmark tại dòng 1.
#6  <-- di chuyển tới dòng 6.
hello from file3.txt
#'x  <-- gọi bookmark x
Change first line.  <--- quay về dòng 1.
#

Ta cũng có thể run các câu lệnh trong terminal, dùng !

[~/ed]$ ed -p '#' text.txt
114
#,pn
1	Change first line.
2	insert second line.
3	Second line.
4	insert second line.
5	hello from file1.txt
6	hello from file3.txt
#! echo "Hello world"   <-- run các lệnh trong terminal
Hello world
!
#! date   <-- in ra ngày giờ hiện tại
Chủ nhật, 12 Tháng 9 năm 2021 15:40:48 +07
!
#0r !date  <-- thêm ngày giờ hiện tại vào dòng đầu tiên của file.
49
#,pn
1	Chủ nhật, 12 Tháng 9 năm 2021 15:41:09 +07
2	Change first line.
3	insert second line.
4	Second line.
5	insert second line.
6	hello from file1.txt
7	hello from file3.txt
#wq
163
[~/ed]$ 

Còn nếu muốn xuất terminal comamnd ra buffer mới ta dùng 'e ! '.

[~/ed]$ ed -p '#' text.txt   
163
#,pn
1	Chủ nhật, 12 Tháng 9 năm 2021 15:41:09 +07
2	Change first line.
3	insert second line.
4	Second line.
5	insert second line.
6	hello from file1.txt
7	hello from file3.txt
#e ! date 
49
#,pn
1	Chủ nhật, 12 Tháng 9 năm 2021 15:57:44 +07
#w today.txt
49
#q
[~/ed]$ cat today.txt
Chủ nhật, 12 Tháng 9 năm 2021 15:57:44 +07
[~/ed]$ 

Search và replace 1 dòng trong ed. Để search và repalce 1 dòng ta dùng 's/search/replace/p' p có nghĩa là in ra.

[~/ed]$ ed -p '#' text.txt
163
#,pn
1	Chủ nhật, 12 Tháng 9 năm 2021 15:41:09 +07
2	Change first line.
3	insert second line.
4	Second line.
5	insert second line.
6	hello from file1.txt
7	hello from file3.txt
#2
Change first line.
#s/first/xxx/p
Change xxx line.
#  

Nếu trên 1 dòng có nhiều từ 'first', ví dụ

first first first.

Ta muốn search từ first và thay đổi ở từ first thứ 2 thì sao ? Ta gõ s/first/xxx/2p. 2 là vị trí 2.

[~/ed]$ ed -p '#' text.txt
163
#a
first first first
.
#,pn
1	Chủ nhật, 12 Tháng 9 năm 2021 15:41:09 +07
2	Change first line.
3	insert second line.
4	Second line.
5	insert second line.
6	hello from file1.txt
7	hello from file3.txt
8	first first first
#8
first first first
#s/first/xxx/2p
first xxx first
#q
?
#q
[~/ed]$ 

Nếu muốn search và replace tất cả trên 1 dòng, ta dùng g.

#,pn
1	Chủ nhật, 12 Tháng 9 năm 2021 15:41:09 +07
2	Change first line.
3	insert second line.
4	Second line.
5	insert second line.
6	hello from file1.txt
7	hello from file3.txt
8	first first first
#s/first/xxx/g
#,pn
1	Chủ nhật, 12 Tháng 9 năm 2021 15:41:09 +07
2	Change first line.
3	insert second line.
4	Second line.
5	insert second line.
6	hello from file1.txt
7	hello from file3.txt
8	xxx xxx xxx
#

Còn search và replace trên nhiều dòng ta dung g/search/\ , \ tiếp sau là command nữa.

[~/ed]$ ed -p '#' search.txt
44
#,pn
1	first first first.
2	first line.
3	second line.
#g/first/\  <-- search tất cả dòng.
s/first/xxx/p  <-- search từ first replace bằng xxx và p là in ra
first first first.  <-- dòng ban đầu 
xxx first first.  <-- dòng sau khi replace.
first line. <-- dòng ban đầu
xxx line.  <-- dòng sau khi replace.
#,pn
1	xxx first first.
2	xxx line.
3	second line.
#

còn nếu search và replace toàn file luôn.

[~/ed]$ ed -p '#' search.txt
44
#,pn
1	first first first.
2	first line.
3	second line.
#g/first/\   <-- search tất cả first
s/first/xxx/gp  <-- search từ first và replace bằng xxxx, g tất cả trường hợp trên 1 dòng
first first first.
xxx xxx xxx.
first line.
xxx line.
#,pn
1	xxx xxx xxx.
2	xxx line.
3	second line.
#

Hoăc ta cũng có thể gõ trên cùng 1 dòng.

[~/ed]$ ed -p '#' search.txt
44
#,pn
1	first first first.
2	first line.
3	second line.
#g/first/s/first/xxxx/gp
xxxx xxxx xxxx.
xxxx line.
#

Nếu ta muốn xóa từ mà mình search thì dung như sau.

#,pn
1	first first first.
2	first line.
3	second line.
#3    <-- di chuyển dòng 3.    
second line.
#s/line//  <-- search line và replace bằng rỗng.
#,pn
1	first first first.
2	first line.
3	second .
#

Ta có thể lưu các lệnh của ed ra dạng file, và có thể dùng các lệnh này thay đổi nội dung của file khác. Ví dụ ta sẽ thay đổi chữ Install thành Setup trong file 'file.md'.

[~/ed]$ cat file.md
-------------------------------
pageTitle: Install Arch Linux.
-------------------------------


# Install Arch Linux.

I love Arch Linux.
[~/ed]$ cat filter.ed 
g/Install/\
s/Install/Setup/gp
w
q
[~/ed]$ cat filter.ed  | ed file.md
139
pageTitle: Install Arch Linux.
pageTitle: Setup Arch Linux.
# Install Arch Linux.
# Setup Arch Linux.
135
[~/ed]$ cat file.md
-------------------------------
pageTitle: Setup Arch Linux.
-------------------------------


# Setup Arch Linux.

I love Arch Linux.
[~/ed]$ 

Bài viết này hơi dài nhưng nếu bạn đọc và thực hành hết bài viết này thì chúc mừng bạn đã có một text editor mạnh mẽ để sử dụng. Chúc vui và hẹn gặp lại. ^_^