5 คำสั่ง Bash แบบบรรทัดเดียวที่ทำให้ฉันกลับมาใช้เทอร์มินัล Linux อยู่เสมอ
คุณใช้เวลาส่วนใหญ่ของคุณในเทอร์มินัลหรือไม่? คุณมักมองหาวิธีปรับปรุงทักษะเทอร์มินัลของคุณอยู่เสมอหรือไม่? ถ้าคุณเหมือนผม คุณคงชอบเรียนรู้วิธีใหม่ๆ ในการแก้ปัญหา เพราะมันแนะนำแนวคิดที่คุณไม่เคยจินตนาการมาก่อน ผมมีคำสั่งเทอร์มินัลแบบบรรทัดเดียวห้าคำสั่งที่ช่วยแก้ปัญหาที่พบบ่อย และบางทีอาจจะแนะนำแนวคิดใหม่ๆ ให้คุณด้วยเช่นกัน
Mkdir พร้อมการขยายวงเล็บ
การขยายวงเล็บช่วยลดความยาวคำสั่งและใช้กับทุกอย่าง
อันแรกนี้เป็นเทคนิคที่ใช้ซ้ำได้ซึ่งสามารถใช้ได้มากกว่าคำสั่งเดียว
mkdir --parents foo/{bar,baz}คำสั่งนั้นจะสร้างโครงสร้างไดเร็กทอรีดังนี้:
foo/
├── bar/
└── baz/แฟลก "--parents" (หรือ -p) รับประกันได้ว่าคุณสมบัติของไดเรกทอรีต้นทางจะถูกสร้างก่อน ส่วนวงเล็บปีกกาเป็นที่ซึ่งเวทมนตร์เกิดขึ้น ใน Bash พวกมันถูกเรียกว่า brace expansions และมันง่ายมาก Bash จะจัดการคำสั่งข้างต้นเหมือนว่า:
mkdir --parents foo/bar
mkdir --parents foo/baz
คุณสามารถใช้การขยายวงเล็บกับคำสั่งใดก็ได้ จากเอกสารทางการ:
chown root /usr/{ucb/{ex,edit},lib/{ex?.?*,how_ex}}Bash จะประเมินวงเล็บเคล็ดลับด้านในก่อน และนิพจน์เส้นทางก่อนหน้ากลายเป็นดังต่อไปนี้:
/usr/ucb/ex
/usr/ucb/edit
/usr/lib/ex?.?*
/usr/lib/how_ex"?" และ "*" เป็นกลอบ (globs) ซึ่งตรงกับตัวอักษรเดียวและศูนย์หรือตัวอักษรมากกว่าหนึ่งตัวตามลำดับ
ฉันมักจะใช้การขยายวงเล็บตรง ๆ กับ mkdir ดังนั้นอย่าให้การแสดงออกที่สอง (ซับซ้อน) ทำให้คุณท้อใจ
จำนวนบรรทัดหรือคำ
สร้างสตรีมเดียวและส่งผ่านไปยัง wc
ฉันใช้คำสั่งนี้เป็นครั้งคราวเพื่อนับจำนวนบรรทัดของโค้ดในโครงการซอฟต์แวร์ของฉันหรือคำในบันทึกของฉัน
cat **/*.go | wc --lines # Count code lines.
cat **/*.org | wc --words # Count words in notes.เพื่อที่จะทำการนับทั้งหมด เราจำเป็นต้องมีสตรีมข้อมูลเดียวที่ถูกส่งเข้าไปใน "wc." ถ้าเราเพียงแค่รัน wc --words **/*.org เราจะได้ผลลัพธ์หลายร้อยรายการ หนึ่งรายการสำหรับแต่ละไฟล์ คำสั่งที่ระบุแต่ละคำสั่งจะส่งสตรีมข้อมูลเดียวเข้าไป
เปรียบเทียบผลลัพธ์ของกระบวนการสองตัว
การแทนที่กระบวนการทำให้คำสั่ง diff มีประโยชน์มากขึ้น
คุณอาจคุ้นเคยกับ diff ซึ่งช่วยให้คุณเปรียบเทียบไฟล์สองไฟล์ได้:
diff foo.txt bar.txtอย่างไรก็ตาม คุณอาจไม่ทราบเกี่ยวกับการแทนที่กระบวนการ สิ่งเหล่านี้ช่วยให้คุณสามารถเรียกใช้คำสั่งสองคำสั่งใดก็ได้และส่งผลลัพธ์ของมัน (เป็นเส้นทางไปยังไฟล์ชั่วคราว) ให้กับคำสั่งเช่น diff:
diff <(ls ./foo) <(ls ./bar)
เมื่อพิจารณาโครงสร้างไดเรกทอรีดังต่อไปนี้ (ทั้งคู่มีไฟล์ชื่อ "two")
.
├── bar
│ ├── three
│ └── two
└── foo
├── one
└── twoเครื่องหมาย ">" บ่งชี้ว่าการแทนที่กระบวนการทางด้านขวา ("<(ls ./bar)") แสดงรายการไฟล์ชื่อ "three" แต่ด้านซ้ายไม่แสดง หลักการเดียวกันนี้ใช้กับ "<" ด้วย
แนวทางที่มีประโยชน์มากกว่าคือการสร้างเกณฑ์มาตรฐานของไดเรกทอรี (ls ~/foo > foo-baseline.txt) และเปรียบเทียบกับรายการปัจจุบัน:
diff foo-baseline.txt <(ls ~/foo)ตอนนี้เราสามารถเห็นการเปลี่ยนแปลงใด ๆ ในไดเรกทอรี สิ่งนี้มีประโยชน์มากโดยเฉพาะเมื่อใช้ watch (ซึ่งจะกล่าวถึงในหัวข้อต่อไป)
การแทนที่ด้วยกระบวนการช่วยให้คุณเปรียบเทียบคำสั่งใด ๆ สองคำสั่งได้ ดังนั้นคุณสามารถปล่อยจินตนาการของคุณไปไกลกว่าคำสั่ง "ls" ธรรมดา ๆ
ดูผลลัพธ์ของคำสั่ง
การเฝ้าติดตามการเปลี่ยนแปลงมักจำเป็น และคำว่า "watch" มีความยืดหยุ่น
ยูทิลิตี้ "watch" นั้นเรียบง่ายมาก: มันจะตรวจสอบคำสั่งทุกสองวินาที ทำให้คุณสามารถติดตามมันเพื่อดูการเปลี่ยนแปลงได้
ตัวอย่างง่ายๆ คือการตรวจสอบพอร์ตที่กำลังฟัง:
watch ss -altpnมันล้างหน้าจอและแสดงเฉพาะผลลัพธ์ของคำสั่งพร้อมหัวข้อขนาดเล็ก
แฟล็ก --color แปลความรหัส ANSI และ --differences แสดงการเปลี่ยนแปลงระหว่างรอบการทำซ้ำ อย่างไรก็ตาม ผลลัพธ์แตกต่างกันไป และค่อนข้างไม่น่าเชื่อถือ
เราสามารถใช้ "watch" เพื่อตรวจสอบไดเรกทอรีของเราและแสดงความแตกต่างได้:
watch "bash -c 'diff foo-baseline.txt <(ls -1 foo/)'"คำสั่ง "watch" ใช้ sh ซึ่งไม่มีการแทนที่กระบวนการของ Bash ให้รันคำสั่ง diff ผ่าน Bash โดยตรงเพื่อเปิดใช้งานฟีเจอร์นั้น
การสร้างไฟล์ ("1") ทำให้มันปรากฏใน diff ("2") ตอนนี้คุณจะได้รับอัปเดตเกือบเรียลไทม์เกี่ยวกับการเปลี่ยนแปลงในไดเรกทอรีในรูปแบบ diff
ค้นหาด้วย Grep ระหว่างรูปแบบเฉพาะ
บางครั้งคุณอาจต้องการตัดส่วนของข้อความออก
Grep จับคู่ทั้งบรรทัดทั้งหมด แต่บางครั้งคุณอาจต้องการเพียงส่วนที่ตรงกับรูปแบบเท่านั้น ตัวอย่างเช่น หากคุณต้องการดึงเฉพาะ เนื้อหา ของแท็ก HTML:
<body>
<p>The text we care about.</p>
</body>grep -oP '(?<=<p>).+(?=</p>)'- "-o": คืนเฉพาะส่วนที่ตรงกันของบรรทัด ไม่ใช่ทั้งหมด
- "-P": ใช้ regex แบบเข้ากันได้กับ Perl ซึ่งช่วยให้สามารถใช้ positive lookaheads และ lookbehinds ได้
- "(?<=
)": การมองย้อนกลับเชิงบวก หมายถึงว่า เมื่อจับคู่รูปแบบ (".+") เครื่องยนต์จะมองย้อนกลับไปเพื่อดูว่า "
" ก็ตรงกันด้วยหรือไม่
- "(?=)": การมองไปข้างหน้าแบบบวก มันคล้ายกับการมองถอยหลังแบบบวก แต่จะมองไปข้างหน้า
โดยพื้นฐานแล้ว regex จะจับคู่กับ ".+" (อักขระใด ๆ หนึ่งตัวหรือมากกว่า) และตรวจสอบทั้งสองด้านเพื่อดูว่า "
" และ "
" ตรงกันด้วยหรือไม่ หากไม่ตรงกัน การจับคู่จะล้มเหลว ซึ่งช่วยให้เราสามารถเน้นแท็ก "p" ได้ คุณสามารถใช้รูปแบบใดก็ได้ตามที่คุณต้องการ; ฉันใช้ HTML เป็นเพียงตัวอย่างเท่านั้น ตัวอย่างเช่น:grep -oP '(?<=foo).+(?=bar)'คำสั่งนั้นจะตรงกับอะไรก็ได้ระหว่าง "foo" และ "bar"
เวอร์ชันเก่าของ PCRE จะยอมรับเฉพาะ lookbehind ที่ความยาวคงที่เท่านั้น (ไม่อนุญาตให้ใช้ ?, + หรือ *) อย่างไรก็ตาม ตั้งแต่เวอร์ชัน 10.43 (PCRE2) จะอนุญาตให้มีขีดจำกัดปรับได้ (ค่าเริ่มต้น 255 ตัวอักษร) ขีดจำกัดนี้ถูกตั้งขึ้นเพื่อป้องกันการประมวลผลที่มีประสิทธิภาพต่ำ การรัน grep --version ควรจะแสดงว่าใช้เวอร์ชัน PCRE ใด
ฉันมีคู่มือเกี่ยวกับ regex ที่ละเอียดกว่านี้ซึ่งอาจทำให้คุณสนใจ มันครอบคลุมทุกองค์ประกอบพื้นฐาน
คำสั่งเหล่านี้ขึ้นอยู่กับสถานการณ์เป็นอย่างมาก แต่ก็ให้ข้อมูลเชิงลึกที่สามารถนำไปใช้กับคำสั่งอื่น ๆ ได้หลายคำสั่ง การขยายเครื่องหมายวงเล็บใช้ได้กับเกือบทุกคำสั่งที่นึกออกและมีประโยชน์โดยเฉพาะกับเส้นทางระบบไฟล์ Watch คือสิ่งที่ฉันใช้บ่อย และ diffs ครอบคลุมสถานการณ์ที่เราต้องติดตามการเปลี่ยนแปลง Grep และ regex มีความสามารถอย่างมาก แต่ก็มีหลายโอกาสในอดีตที่ฉันไม่สามารถตัดส่วนของข้อความออกได้—ตอนนี้ฉันรู้วิธีแล้ว และคุณก็เช่นกัน





