ประมวลผลไฟล์ / etc / passwd เพื่อแสดงรายการผู้ใช้ทั้งหมดที่มีโฮมโฟลเดอร์อยู่ใน / home


10

ฉันมีตัวอย่างไฟล์ / etc / passwd ดังนี้:

tom:x:1000:1000:Work:/home/tom:/bin/bash
george:x:1000:1000:Work:/home/george:/bin/bash
bla:x:1000:1000:Work:/home/bla:/bin/bash
boo:x:1000:1000:Work:/home/boo:/bin/bash
bee:x:1000:1000:Work:/root/list:/bin/bash

/home/ฉันพยายามที่จะแสดงรายชื่อผู้ใช้ทั้งหมดที่มีบ้านในโฟลเดอร์

ฉันเขียน

cat ~/Desktop/e.txt |awk -F ":" '{if ($6 ~/^/home/) print $1;}'

โดยที่ e.txt เป็นข้อความที่ฉันคัดลอกมาที่นี่

ฉันเข้าใจว่ามีปัญหากับแบ็กสแลชซึ่งเป็นอักขระการหลบหนี แต่ฉันจะแก้ไขได้อย่างไรเพื่อให้สามารถแสดงรายการเหล่านั้นในหนึ่งบรรทัดของคำสั่งได้


11
คำแนะนำทั่วไปนอกเหนือจากคำตอบ (ที่มาพร้อมกับเพียงหนึ่งวินาทีในระหว่าง!): มันแทบจะไม่มีเหตุผลที่catจะใช้เครื่องมือเช่นawkหรือsedหรือสิ่งที่คล้ายกันเพราะพวกเขาสามารถให้ชื่อไฟล์เป็นอาร์กิวเมนต์
Philippos

1
cat e.txt | หน้าแรก cut -d ":" -f 1
Arpit Agarwal

3
เนื่องจากผู้ใช้ทุกคนมี UID 1,000 รายการอาจจะยุ่งยากเล็กน้อย
StrongBad

1
grep home e.txt | cut -d ":" -f 1@ArpitAgarwal ขอแสดงความยินดีกับรางวัล UUOC ของคุณ อย่างไรก็ตามนี่ไม่ใช่ทางออกที่ดี จะเกิดอะไรขึ้นถ้ามีบริการ "โฮมแบ็คอัพ" ซึ่งทำงานภายใต้ผู้ใช้ที่แยกต่างหากซึ่งตั้งชื่อตาม daemon? นั่นเป็นสิ่งที่ผิดพลาด
NieDzejkob

2
@Philippos อีกครั้ง "มันแทบจะไม่มีเหตุผลที่จะใช้ cat และ pipe กับเครื่องมือ [ที่] สามารถให้ชื่อไฟล์เป็นอาร์กิวเมนต์ได้" - โดยทั่วไปฉันใช้cat > toolตัวแปรของบรรทัดคำสั่งดังกล่าวเพราะสามารถปรับปรุงความชัดเจนโดยการรักษาทิศทางซ้าย - ขวา ของการประมวลผลอินพุทเอาท์พุทของห่วงโซ่ท่อ มันมีประสิทธิภาพน้อยกว่า แต่แทบจะทุกครั้ง นอกจากนี้ยังทำให้การเพิ่มแถบความคืบหน้าที่เกี่ยวข้องและมีประโยชน์เมื่อทำงานอย่างชัดเจนมากโต้ตอบ (เพียงแทนที่catด้วยpvถ้ามีการติดตั้ง)
David Spillett

คำตอบ:


11

คุณอาจหนีไปข้างหน้าเครื่องหมายทับที่แสดงด้านล่าง:

awk -F':' '$6~/^\/home\//{ print $1 }' ~/Desktop/e.txt

เคล็ดลับอีกอย่างคือการใช้ตัวคั่นฟิลด์ที่ซับซ้อน:

awk -F'[:/]' '$7=="home"{ print $1 }' ~/Desktop/e.txt
  • -F'[:/]'- ปฏิบัติต่อทั้งสอง:และ/เป็นตัวคั่นฟิลด์

2
ฉันเชื่อว่าช่องแสดงความคิดเห็น (ก่อนหน้าไดเรกทอรีบ้าน) ได้รับอนุญาตให้มีเครื่องหมายทับ

12

คุณสามารถใช้เครื่องหมายคำพูดแทน/regex เพื่อหลีกเลี่ยงการหลบหนี/:

awk -F: '$6 ~ "^/home/" {print $1}' ~/Desktop/e.txt

ด้วยawk, สามารถมักจะง่ายเพียงแค่{if (foo) ... }foo {...}


8

สมมติว่าe.txtเป็นจริง/etc/passwdคุณควรใช้getent passwdแทนการแยกวิเคราะห์ไฟล์เนื่องจากข้อมูลบัญชีผู้ใช้อาจถูกเก็บไว้ในหลาย ๆ สถานที่ที่ระบุ/etc/nsswitch.confเช่น LDAP

getent passwd | awk -F ':' '$6 ~ "^/home"'

โปรดทราบว่าprintคำสั่งนั้นส่อให้เห็นเมื่อเงื่อนไขเป็นจริง ที่จะพิมพ์ทั้งบรรทัดแม้ว่า สิ่งนี้จะพิมพ์เฉพาะชื่อผู้ใช้:

getent passwd | awk -F ':' '$6 ~ "^/home" {print $1}'

4

ทางเลือกสำหรับพวกเราที่ไม่ชอบ awk:

grep -E '^([^:]*:){5}/home/' ~/Desktop/e.txt | cut -d: -f1

คำอธิบาย:

  • grep -E เปิดใช้งานการใช้คุณสมบัติการแสดงผลปกติที่ขยายเพิ่ม
  • นิพจน์([^:]*:)ตรงกับหนึ่งคอลัมน์รวมถึงตัวคั่น ':' ต่อไปนี้
  • ^([^:]*:){5} ตรงกับห้าคอลัมน์แรกของแต่ละบรรทัด
  • ^([^:]*:){5}/home/ ตรงกับทุกบรรทัดที่คอลัมน์ที่ 6 เริ่มต้นด้วย '/ home /'
  • cut -d: -f1เลือกเฉพาะคอลัมน์แรกของอินพุตโดยใช้:เป็นตัวคั่นคอลัมน์

3

คุณยังสามารถใช้indexสำหรับการจับคู่สตริงคงที่เช่นgrep -Fและใช้ค่าส่งคืนเพื่อให้แน่ใจว่าตรงกับจุดเริ่มต้นของสตริง

$ awk -F: 'index($6,"/home/")==1{print $1}' ip.txt
tom
george
bla
boo

หรือถ้าต้องการ regex ให้ส่งผ่านเป็นตัวแปรสภาวะแวดล้อม

$ r='^/home/' awk -F: '$6 ~ ENVIRON["r"]{print $1}' ip.txt
tom
george
bla
boo

3

เพียงเพื่อความหลากหลาย

$ perl -F: -lane 'print $F[0] if m(/home/)' e.txt
tom
george
bla
boo

คำอธิบาย

-F:     use ":" as field separator  
-lane
    l   add newline line-ending to every print statement
    a   auto-split input lines into @F array
    n   apply expression line by line to named file (or STDIN)
    e   evaluate perl commands given on command line

print $F[0]   print (only) the first field of each line
if m(/home/)  but only if the line contains the text /home/

การเปลี่ยนแปลงถ้าคุณต้องการที่จะจู้จี้จุกจิกเกี่ยวกับการที่/home/จะพบ

perl -F: -lane 'print $F[0] if $F[5] =~ m(^/home/)' e.txt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.