คำสั่ง sed: การแทนที่สตริง การลบบรรทัด และการใช้ตัวเลือก -i
คำสั่ง sed คือเครื่องมือ Linux ที่อ่านไฟล์ทีละบรรทัดแล้วดำเนินการแทนที่ ลบ และแทรก คุณจึงแก้ไขค่าในไฟล์การตั้งค่าได้โดยไม่ต้องเปิดโปรแกรมแก้ไข เมื่อเรารัน sed กับสำเนาของ wp-config.php ของ WordPress บนเซิร์ฟเวอร์ AlmaLinux 9 ก็สามารถเปลี่ยนชื่อฐานข้อมูลได้โดยเก็บไฟล์ต้นฉบับไว้ด้วย -i.bak
ข้อความแสดงข้อผิดพลาดในบทความนี้เป็นข้อความตามจริงที่แสดงภายใต้ locale ภาษาอังกฤษ
1️⃣ วิธีใช้พื้นฐานของคำสั่ง sed และการแทนที่ด้วย s
คำสั่ง s ที่ใช้บ่อยที่สุดจะแทนที่สตริงในรูปแบบ [s/สตริงที่ค้นหา/สตริงใหม่/] โดยแทนที่เฉพาะรายการแรกที่พบในแต่ละบรรทัด
echo 'http://example.com http://example.com/blog' | sed 's/http:/https:/'https://example.com http://example.com/blogถ้าต้องการแทนที่ทุกรายการในบรรทัด ให้ใส่แฟล็ก g ต่อท้าย
echo 'http://example.com http://example.com/blog' | sed 's/http:/https:/g'https://example.com https://example.com/blogถ้าใส่ชื่อไฟล์ไว้ท้ายคำสั่ง sed จะอ่านไฟล์นั้นแล้วแสดงผลที่แทนที่แล้ว ในสำเนาที่คัดลอก wp-config-sample.php ของ WordPress เป็น wp-config.php เราเปลี่ยนค่า DB_USER และตรวจเฉพาะบรรทัดนั้นด้วย grep
sed 's/username_here/wp_user/' wp-config.php | grep DB_USERdefine( 'DB_USER', 'wp_user' );เมื่อเห็นค่าในเอาต์พุตเปลี่ยนไปก็อาจเข้าใจว่าไฟล์เปลี่ยนด้วย แต่ถ้ารัน sed โดยไม่มีตัวเลือก จะแสดงผลบนหน้าจออย่างเดียวและไม่แตะไฟล์ต้นฉบับ เมื่อค้นบรรทัดเดิมในไฟล์อีกครั้ง ค่าเดิมก็ยังอยู่
grep DB_USER wp-config.phpdefine( 'DB_USER', 'username_here' );ถ้าต้องการเปลี่ยนไฟล์ต้นฉบับด้วย ให้ใช้ตัวเลือก -i ในหัวข้อ 4️⃣
2️⃣ การเลือกบรรทัดใน sed ด้วยหมายเลขบรรทัดและแพตเทิร์น (-n, p)
คำสั่ง s ที่ไม่มีแอดเดรสจะทำงานกับทุกบรรทัด ถ้าต้องการจัดการเฉพาะบางบรรทัด ให้เขียนหมายเลขบรรทัดหรือแพตเทิร์นเป็นแอดเดรสไว้หน้าคำสั่ง -n ปิดการแสดงผลอัตโนมัติ และ p แสดงบรรทัดที่เลือก เมื่อใช้ร่วมกันจะเห็นเฉพาะบรรทัดที่ 23
sed -n '23p' wp-config.phpdefine( 'DB_NAME', 'database_name_here' );ถ้าคั่นหมายเลขบรรทัดสองตัวด้วยจุลภาคจะได้ช่วงนั้น บรรทัดที่ 23 ถึง 32 คือส่วนที่มีการตั้งค่าชื่อฐานข้อมูล ผู้ใช้ รหัสผ่าน และโฮสต์
sed -n '23,32p' wp-config.phpdefine( 'DB_NAME', 'database_name_here' );
/** Database username */
define( 'DB_USER', 'username_here' );
/** Database password */
define( 'DB_PASSWORD', 'password_here' );
/** Database hostname */
define( 'DB_HOST', 'localhost' );ถ้าเขียนแพตเทิร์นระหว่างเครื่องหมายทับแทนหมายเลขบรรทัด จะเลือกทุกบรรทัดที่มีแพตเทิร์นนั้น
sed -n '/DB_/p' wp-config.phpdefine( 'DB_NAME', 'database_name_here' );
define( 'DB_USER', 'username_here' );
define( 'DB_PASSWORD', 'password_here' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );คำสั่ง [=] แสดงหมายเลขของบรรทัดที่เลือก แอดเดรส $ หมายถึงบรรทัดสุดท้าย จึงใช้ [$=] ดูจำนวนบรรทัดทั้งหมดของไฟล์ได้
sed -n '/DB_HOST/=' wp-config.php32sed -n '$=' wp-config.php102แอดเดรสใส่หน้าคำสั่ง s ได้เช่นกัน ด้านล่างคือผลการเปลี่ยน localhost เฉพาะบรรทัดที่ 32 และแสดงเฉพาะบรรทัดที่เปลี่ยนด้วยแฟล็ก p
sed -n '32s/localhost/127.0.0.1/p' wp-config.phpdefine( 'DB_HOST', '127.0.0.1' );เมื่อรัน p โดยไม่มี -n บรรทัดที่เลือกจะแสดงอีกครั้ง sed อ่านทีละบรรทัดเข้า pattern space รันคำสั่ง แล้วแสดง pattern space โดยอัตโนมัติ บรรทัดที่ 2 ที่ p แสดงไปแล้วจึงปรากฏอีกครั้งจากการแสดงผลอัตโนมัติ
sed '2p' wp-config.php | head -n 4<?php
/**
/**
* The base configuration for WordPressวิธีอ่านและประมวลผลทีละบรรทัดนี้เหมือนสายพานในโรงงานที่วางชิ้นส่วนทีละชิ้นบนโต๊ะงาน แปรรูปแล้วจึงไปยังชิ้นถัดไป
คุณเปรียบเทียบได้ทีละขั้นในแผนภาพด้านล่างว่าแต่ละคำสั่งแสดงอะไรในแต่ละบรรทัด
3️⃣ การลบและแทรกบรรทัดด้วยคำสั่ง sed (d, i, a)
d ลบบรรทัดที่เลือก ถ้าต้องการดูตัวอย่างการตั้งค่า nginx ด้านล่างโดยไม่มีบรรทัดคอมเมนต์ ให้เลือกบรรทัดที่ขึ้นต้นด้วย # หรือมีเพียงช่องว่างหน้า # ด้วยแพตเทิร์น [^ *#]
cat example.conf# example.com
server {
listen 80;
server_name example.com www.example.com;
# document root
root /var/www/example.com;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
}sed '/^ *#/d' example.confserver {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
}ถ้าเชื่อมคำสั่งด้วยเครื่องหมายอัฒภาค จะลบ [^$] ซึ่งหมายถึงบรรทัดว่างไปด้วย บรรทัดว่างสองบรรทัดที่เหลือหลังลบคอมเมนต์หายไป เหลือเฉพาะบรรทัดการตั้งค่า
sed '/^ *#/d; /^$/d' example.confserver {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
}i แทรกข้อความหน้าบรรทัดที่เลือก ส่วน a แทรกหลังบรรทัดที่เลือก ผลของการแทรกคอมเมนต์หนึ่งบรรทัดหน้าบรรทัดที่ 1 เป็นดังนี้
sed '1i # managed by sed' example.conf | head -n 3# managed by sed
# example.com
server {อาจเข้าใจว่าถ้าเขียนข้อความที่ย่อหน้าไว้หลัง a การย่อหน้าจะเข้าไปด้วย แต่ GNU sed จะข้ามช่องว่างหลัง a แล้วแทรกเฉพาะข้อความ
sed '/index index.php/a client_max_body_size 64M;' example.conf# example.com
server {
listen 80;
server_name example.com www.example.com;
# document root
root /var/www/example.com;
index index.php index.html;
client_max_body_size 64M;
location / {
try_files $uri $uri/ /index.php?$args;
}
}ถ้าต้องการคงการย่อหน้า ให้ใส่แบ็กสแลชหลัง a ตั้งแต่ช่องว่างหลังแบ็กสแลชจะเข้าไปเป็นข้อความทั้งหมด
sed '/index index.php/a\ client_max_body_size 64M;' example.conf# example.com
server {
listen 80;
server_name example.com www.example.com;
# document root
root /var/www/example.com;
index index.php index.html;
client_max_body_size 64M;
location / {
try_files $uri $uri/ /index.php?$args;
}
}c แทนที่บรรทัดที่เลือกทั้งบรรทัด ด้านล่างคือสี่บรรทัดแรกของผลการเปลี่ยนบรรทัด listen 80 เป็น 8080
sed '/listen 80;/c\ listen 8080;' example.conf | head -n 4# example.com
server {
listen 8080;
server_name example.com www.example.com;4️⃣ การแก้ไขไฟล์โดยตรงด้วย sed -i และชื่อไฟล์สำรอง
-i บันทึกผลลงไฟล์ต้นฉบับแทนการแสดงบนหน้าจอ ข้อความที่เขียนติดหลัง -i จะต่อท้ายชื่อไฟล์สำรอง wp-config.php และไฟล์อื่นที่เว็บไซต์อ่าน ควรแก้ไขด้วย -i.bak เพื่อเก็บไฟล์ต้นฉบับไว้
cp wp-config-sample.php wp-config.phpsed -i.bak 's/database_name_here/wordpress_db/' wp-config.phpเมื่อรันด้วย -i จะไม่มีอะไรแสดงบนหน้าจอ จึงตรวจไฟล์ด้วย ls -l
ls -l wp-config.php*-rw-r--r-- 1 root root 3333 Oct 28 15:13 wp-config.php
-rw-r--r-- 1 root root 3339 Oct 28 15:13 wp-config.php.bakไฟล์ที่แก้ไขและไฟล์ .bak อยู่คู่กัน ขนาดเล็กลง 6 ไบต์เพราะ database_name_here กลายเป็น wordpress_db ที่สั้นกว่า เมื่อเปรียบเทียบสองไฟล์ด้วย diff จะเห็นเฉพาะบรรทัดที่เปลี่ยน
diff wp-config.php.bak wp-config.php23c23
< define( 'DB_NAME', 'database_name_here' );
---
> define( 'DB_NAME', 'wordpress_db' );บรรทัดที่เปลี่ยนคือบรรทัด DB_NAME บรรทัดเดียวที่บรรทัดที่ 23
ถ้ามีหลายค่าที่ต้องเปลี่ยน ให้เชื่อมสคริปต์ด้วย -e แล้วรันครั้งเดียว
sed -i -e 's/username_here/wp_user/' -e 's/password_here/wp_pass/' wp-config.phpgrep -n -e DB_USER -e DB_PASSWORD wp-config.php26:define( 'DB_USER', 'wp_user' );
29:define( 'DB_PASSWORD', 'wp_pass' );ถ้าเขียน -i กับ -e ติดกันแบบ [-ie] ตัว e จะถูกอ่านเป็นชื่อสำรองด้วย และเกิดไฟล์ wp-config.phpe ดังด้านล่าง
sed -ie 's/127.0.0.1/localhost/' wp-config.phpls wp-config.php*wp-config.php
wp-config.php.bak
wp-config.phpe-i เขียนเนื้อหาที่แก้ไขลงไฟล์ใหม่แล้วเปลี่ยนชื่อเป็นชื่อเดิม หมายเลข inode ของไฟล์จึงต่างกันก่อนและหลังรัน
ls -i wp-config.php207618887 wp-config.phpsed -i 's/localhost/127.0.0.1/' wp-config.phpls -i wp-config.php207618883 wp-config.phpหมายเลข inode ที่เคยเป็น 207618887 ก่อนรันเปลี่ยนเป็น 207618883
ถ้าไม่มีไฟล์หรือไม่ได้ใส่ชื่อไฟล์ จะจบด้วยข้อผิดพลาดด้านล่างและไม่มีไฟล์ใดเปลี่ยน
sed -i 's/x/y/' no-such.phpsed: can't read no-such.php: No such file or directorysed -i 's/x/y/'sed: no input files5️⃣ นิพจน์ปกติของ sed การเปลี่ยนตัวคั่น และตัวเลือก
🔲 นิพจน์ปกติและการเปลี่ยนตัวคั่น
เมื่อเปลี่ยนค่าที่มีเครื่องหมายทับ เช่น พาธ ตัวคั่นของคำสั่ง s จะปนกับเครื่องหมายทับในค่า จึงต้องใส่แบ็กสแลชหน้าเครื่องหมายทับทุกตัวในค่า
sed -n 's/\/var\/www\/example.com/\/srv\/www\/example.com/p' example.conf root /srv/www/example.com;อักขระที่อยู่ถัดจาก s จะเป็นตัวคั่น ถ้าเปลี่ยนเป็น | ซึ่งไม่มีในค่า ก็จะได้ผลเดียวกันโดยไม่ต้องใช้แบ็กสแลช
sed -n 's|/var/www/example.com|/srv/www/example.com|p' example.conf root /srv/www/example.com;จุด (.) ในแพตเทิร์นตรงกับอักขระใดก็ได้หนึ่งตัว ด้านล่างคือผลของแพตเทิร์นที่ค้นหา example.com แต่เปลี่ยน exampleXcom ไปด้วย
echo 'exampleXcom example.com' | sed 's/example.com/test.org/g'test.org test.orgถ้าต้องการค้นหาจุดตามตัวอักษร ให้ใส่แบ็กสแลชไว้หน้าจุด
echo 'exampleXcom example.com' | sed 's/example\.com/test.org/g'exampleXcom test.orgส่วนที่ครอบด้วยวงเล็บเรียกกลับได้ในสตริงใหม่ด้วย [\1] ถ้าใส่ -E จะใช้วงเล็บและ + ได้โดยไม่ต้องมีแบ็กสแลช ด้านล่างคือผลที่คงตัวเลขหลัง listen และเพิ่ม default_server
sed -nE 's/listen ([0-9]+);/listen \1 default_server;/p' example.conf listen 80 default_server;ถ้ารันสคริปต์เดียวกันโดยไม่มี -E วงเล็บจะถูกอ่านเป็นตัวอักษร และเกิดข้อผิดพลาดว่าไม่มีกลุ่มให้เรียกกลับ ถ้าจะใช้โดยไม่มี -E ให้ใส่แบ็กสแลชที่วงเล็บและ +
sed -n 's/listen ([0-9]+);/listen \1 default_server;/p' example.confsed: -e expression #1, char 46: invalid reference \1 on `s' command's RHSsed -n 's/listen \([0-9]\+\);/listen \1 default_server;/p' example.conf listen 80 default_server;[&] ในสตริงใหม่หมายถึงข้อความทั้งหมดที่ตรงกับแพตเทิร์น จึงใส่ # หน้าส่วนที่ตรงเพื่อทำให้บรรทัดนั้นเป็นคอมเมนต์ได้
sed -n 's/server_name .*;/# &/p' example.conf # server_name example.com www.example.com;🔲 ตัวเลือกของคำสั่ง sed
📌 ตัวเลือกหลัก: ผลที่รันในบทความนี้
| ตัวเลือก | หน้าที่ | ผลที่เห็นในบทความนี้ | |
|---|---|---|---|
| -n | ปิดการแสดงผลอัตโนมัติและแสดงเฉพาะบรรทัดที่เลือกด้วย p | sed -n '23p' แสดงเฉพาะบรรทัดที่ 23 ถ้าไม่มี -n 2p จะแสดงบรรทัดที่ 2 สองครั้ง | |
| -i | บันทึกผลลงไฟล์ต้นฉบับแทนหน้าจอ (ข้อความที่ติดหลังจะต่อท้ายชื่อสำรอง) | -i.bak สร้าง wp-config.php.bak และหมายเลข inode เปลี่ยนหลังรัน | |
| -e | เชื่อมหลายสคริปต์แล้วรันครั้งเดียว | DB_USER และ DB_PASSWORD เปลี่ยนพร้อมกัน ถ้าเขียนติดกันเป็น -ie จะเกิดไฟล์สำรอง wp-config.phpe | |
| -E | ใช้นิพจน์ปกติแบบขยาย (ไม่ต้องใส่แบ็กสแลชที่วงเล็บและ +) | แสดง listen 80 default_server; ส่วนสคริปต์เดียวกันที่ไม่มี -E เกิดข้อผิดพลาด [invalid reference] | |
| --follow-symlinks | ใช้ร่วมกับ -i เพื่อแก้ไขไฟล์ต้นฉบับที่ลิงก์ชี้อยู่ | ถ้าไม่ใส่ จะเกิดไฟล์ปกติแทนลิงก์และต้นฉบับคงเดิม ถ้าใส่ ค่าในต้นฉบับจะเปลี่ยน |
📎 ตัวเลือกอื่น: ตามคู่มือทางการ
| ตัวเลือก | หน้าที่ | |
|---|---|---|
| -f | อ่านสคริปต์จากไฟล์แล้วรัน | |
| -r | นิพจน์ปกติแบบขยายเหมือน -E (พกพาได้ดีกว่าคือ -E) | |
| -s | ประมวลผลแต่ละไฟล์แยกกันแทนการต่อเป็นสตรีมเดียว | |
| -z | แบ่งบรรทัดด้วยอักขระ null แทนการขึ้นบรรทัดใหม่ | |
| -u | อ่านอินพุตทีละน้อยและส่งเอาต์พุตบ่อยขึ้น | |
| --posix | ปิดส่วนขยาย GNU ทั้งหมด | |
| --debug | แสดงขั้นตอนการทำงานแบบละเอียด |
🔲 ตัวจำลองคำสั่ง sed
โฟลเดอร์ทำงานของตัวจำลองด้านล่างมีสำเนา wp-config.php และ example.conf คุณพิมพ์คำสั่งที่ผ่านมาได้เอง และตรวจไฟล์ที่เปลี่ยนด้วย -i ได้ด้วย ls -l และ diff
🔢 FAQ & เนื้อหาแนะนำ







ℹ️ ประกาศเรื่องลิงก์แอฟฟิลิเอต
เนื้อหาของเว็บไซต์นี้มีลิงก์แอฟฟิลิเอต หากผู้เข้าชมซื้อสินค้าหรือบริการผ่านลิงก์เหล่านี้ เว็บไซต์นี้จะได้รับค่าคอมมิชชันจากผู้ขาย ในกระบวนการนี้ ราคาที่ผู้ซื้อจ่าย(ราคาจะลดลงเมื่อมีโปรโมชัน↓)จะไม่สูงขึ้นแต่อย่างใด ราคา ส่วนลด และข้อมูลสต็อกที่แสดงเป็นข้อมูล ณ เวลาที่เขียนและอาจต่างจากความเป็นจริง โปรดตรวจสอบกับผู้ขายอีกครั้งก่อนซื้อ การเลือกและการประเมินสินค้าเขียนตามเกณฑ์ของเราเอง และการได้รับค่าคอมมิชชันหรือไม่ไม่มีผลต่อลำดับการแนะนำหรือเนื้อหาการประเมิน