Grep alias - หมายเลขบรรทัดยกเว้นว่าอยู่ในขั้นตอน


25

ฉันต้องการสร้างนามแฝงทุบตีสำหรับ grep ที่เพิ่มหมายเลขบรรทัด:

alias grep='grep -n'

แต่แน่นอนว่าจะเพิ่มหมายเลขบรรทัดในท่อเช่นกัน เวลาส่วนใหญ่ (และไม่มีข้อยกเว้นอยู่ในใจ) ฉันไม่ต้องการหมายเลขบรรทัดภายในไพพ์ไลน์ (อย่างน้อยก็ภายในก็น่าจะดีถ้ามันยังอยู่) และฉันไม่ต้องการเพิ่มเซด / awk / ตัดเข้าไป ไปป์ไลน์เพื่อนำออกไป

บางทีความต้องการของฉันอาจจะง่ายขึ้น "เพียงเพิ่มหมายเลขบรรทัดหาก grep เป็นคำสั่งเดียวในบรรทัด" มีวิธีการทำเช่นนี้โดยไม่ต้องนามแฝงที่น่าเกลียดโดยเฉพาะอย่างยิ่ง?

คำตอบ:


27

คุณสามารถใช้ฟังก์ชั่นใน bash (หรือ POSIX เชลล์) เช่นนี้:

grep() { 
    if [ -t 1 ] && [ -t 0 ]; then 
        command grep -n "$@"
    else 
        command grep "$@"
    fi
}

[ -t 1 ]ส่วนหนึ่งใช้[คำสั่ง(หรือเรียกว่าtest)เพื่อตรวจสอบว่า stdout มีความเกี่ยวข้องกับ TTY บริการ

[ -t 0 ]ตรวจสอบเข้ามาตรฐานเช่นกันเนื่องจากคุณระบุการเพิ่มเพียงหมายเลขบรรทัดถ้าgrepเป็นเพียงคำสั่งในท่อ


5
และทำการทดสอบ[[ -t 0 && -t 1 ]]หากคุณต้องการเพียงหมายเลขบรรทัดหากทั้งอินพุตมาตรฐานและเอาต์พุตมาตรฐานเชื่อมต่อกับเทอร์มินัล
Gilles 'หยุดความชั่วร้าย'

3

(เพื่อความสมบูรณ์)

แม้ว่าคำตอบของ @ enzotibอาจเป็นสิ่งที่คุณต้องการมากที่สุด แต่ก็ไม่ใช่สิ่งที่คุณต้องการ [ -t 1 ]ตรวจสอบว่า file descriptor เป็นอุปกรณ์เทอร์มินัลไม่ใช่ว่ามันเป็นอย่างอื่นนอกจากไพพ์ (เช่นไฟล์ปกติซ็อกเก็ตอุปกรณ์ประเภทอื่นเช่น/dev/null... )

[คำสั่งมีเทียบเท่าไม่-tแต่สำหรับท่อ ในการรับชนิดของไฟล์ที่เชื่อมโยงกับ file descriptor คุณจะต้องทำการfstat()เรียกระบบ ไม่มีคำสั่งมาตรฐานที่จะทำเช่นนั้น แต่บางระบบหรือเชลล์มีบางคำสั่ง

ด้วย GNU stat:

grep() {
  if { [ "$(LC_ALL=C stat -c %F - <&3)" = fifo ]; } 3>&1 ||
     [ "$(LC_ALL=C stat -c %F -)" = fifo ]; then
    command grep "$@"
  else
    command grep -n "$@"
  fi
}

หรือด้วยzshและstatbuiltin ของตัวเอง(ซึ่งมีมาก่อน GNU ของไม่กี่ปี) โหลดที่นี่zstatเพียง

grep() {
  zmodload -F zsh/stat b:zstat
  local stdin_type stdout_type
  if zstat -A stdin_type -s -f 0 +mode &&
     zstat -A stdout_type -s -f 1 +mode &&
     [[ $stdin_type = p* || $stdout_type = p* ]]
  then
     command grep "$@"
  else
     command grep -n "$@"
  fi
}

ตอนนี้บันทึกไม่กี่:

มันไม่ได้เป็นเพียงเปลือกท่อที่ใช้ท่อ

var=$(grep foo bar)

หรือ:

cmd <(grep foo bar)

หรือ:

coproc grep foo bar

ยังทำงานgrepด้วย stdout ของมันจะไปป์

หากเปลือกของคุณksh93ทราบว่าในบางระบบมันจะใช้ซ็อกเก็ตคู่แทนท่อในท่อ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.