ฉันจะทดสอบได้อย่างไรว่าตัวแปรมีหลายบรรทัดที่ไม่ใช่ช่องว่างในทุบตี?


10

ว่าฉันมีสองตัวแปรในทุบตี:

MULTILINE="I have
more than one line"
SINGLE_LINE="I only have one line
"

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

ดังนั้นนี่คือ:

if [ some test on "$MULTILINE" ]; then echo 'yes'; else echo 'no'; fi

จะพิมพ์yesและสิ่งนี้:

if [ some test on "$SINGLE_LINE" ]; then echo 'yes'; else echo 'no'; fi

noจะพิมพ์

สำหรับกรณีเฉพาะของฉันฉันไม่คิดว่าฉันต้องกังวลเกี่ยวกับการนำบรรทัดว่างเปล่า แต่จะไม่เจ็บที่จะรู้วิธีการทำเช่นนั้น

ฉันจะทำสิ่งนี้ได้อย่างไร



@ krowe ขอบคุณ แต่คุณสามารถชี้ไปที่คำตอบเฉพาะที่ไม่สนใจบรรทัดว่างที่ตามมาได้หรือไม่? ฉันไม่เห็นเลย (แก้ไขชื่อให้ถูกต้องด้วย)
jpmc26

คำตอบ:


5

ทางออกที่ง่ายที่สุดที่ฉันรู้คือ:

if (( $(grep -c . <<<"$MULTILINE") > 1 ))

เช่น:

VAR="a
b"
if (( $(grep -c . <<<"$VAR") > 1 )); then
  echo VAR has more than one line
else
  echo VAR has at most one line
fi

==>

VAR has more than one line

ด้านบนไม่สนใจบรรทัดว่างทั้งหมด: นำหน้าต่อท้ายและตกแต่งภายใน แต่โปรดทราบว่ามันเป็นไปไม่ได้ที่จะมีบรรทัดว่างภายในถ้ามีอย่างน้อยสองบรรทัดที่ไม่ใช่ช่องว่างดังนั้นการมีอยู่ของมันไม่สามารถแก้ไขคำถามได้ว่ามีมากกว่าหนึ่งบรรทัดหลังจากการตัดแต่งบรรทัดว่างที่นำหน้าและต่อท้าย


5
$ echo "$ MULTILINE" | ห้องสุขา -l
2

$ echo "$ SINGLE_LINE" | ห้องสุขา -l
2

$ echo "$ SINGLE_LINE" | sed -re '/ ^ $ / d' | ห้องสุขา -l
1

$ echo "$ MULTILINE" | sed -re '/ ^ $ / d' | ห้องสุขา -l
2

ดู/programming/16414410/delete-empty-lines-using-sed
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการตัด / ลบช่องว่างและบรรทัดว่างโดยใช้ sed

ตอนนี้เพื่อเขียนการif expression ...ใช้งาน ของคุณ$( ... )ภายในเครื่องหมายคำพูดเพื่อรับจำนวนบรรทัดและทดสอบกับจำนวน:

ถ้า ["$ (echo" $ MULTILINE "| sed -re '/ ^ $ / d' | wc -l)" -gt 1]; แล้วก็
  echo 'มากกว่าหนึ่งบรรทัด'; 
อื่น 
  echo 'บรรทัดเดียวหรือไม่มีเลย'; 
Fi

0

การแก้ไขโค้ดนี้เล็กน้อยควรทำ คุณสามารถใส่ไว้ในสคริปต์ของตัวเองเพื่อนำมาใช้ใหม่เช่นนี้:

#!/bin/bash
nlhit=""
for (( i=0; i<${#1}; i++ )); do
    if [[ "${1:$i:1}" == $'\n' ]]; then
        nlhit="1"
    elif [[ "$nlhit" == "1" ]]; then
        exit 1
    fi
done

exit 0

จากนั้นคุณสามารถใช้มันได้เช่นกัน (สมมติว่าคุณตั้งชื่อสคริปต์ก่อนหน้าmultiline-check.sh):

#!/bin/bash

EMPTYLINE=""
BLANKLINE="    "
ONLYLINES="


"

MULTILINE="I have
more than one line"
SINGLE_LINE="I only have one line
"
SECOND_LINE="
I begin with a newline"


echo -n "EMPTYLINE Check: "
multiline-check.sh "$EMPTYLINE"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi

echo -n "BLANKLINE Check: "
multiline-check.sh "$BLANKLINE"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi

echo -n "ONLYLINES Check: "
multiline-check.sh "$ONLYLINES"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi

echo -n "MULTILINE Check: "
multiline-check.sh "$MULTILINE"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi

echo -n "SINGLE_LINE Check: "
multiline-check.sh "$SINGLE_LINE"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi

echo -n "SECOND_LINE Check: "
multiline-check.sh "$SECOND_LINE"
if [ $? -eq 1 ]; then echo "Yes"; else echo "No"; fi

fiฉันได้รับไวยากรณ์ผิดพลาดในครั้งแรก น่าเสียดายที่ฉันติด bash 3.1 (รุ่น msysgit) ฉันไม่เห็นสิ่งใดที่ดูเหมือนข้อผิดพลาดทางไวยากรณ์สำหรับฉัน แต่เห็นได้ชัดว่าฉันขาดอะไรไป คิด?
jpmc26

@ jpmc26 มันมีข้อผิดพลาด ฉันได้อัปเดตเป็นสคริปต์ภายนอกเพื่อให้ใช้งานได้ง่ายขึ้น
krowe

@ jpmc26 ฉันได้เพิ่มการตรวจสอบเพิ่มเติมเพื่อทดสอบการป้อนข้อมูลคี่อื่น ๆ
krowe

0

ละเว้นบรรทัดว่างต่อท้าย

นี่คือวิธีการใช้awk:

echo "$TEST" | tac | awk 'f==0 && /./ {f=NR} END{if(f==NR){exit 0}; exit 1 }' && echo "Found A Single Line"

มันทำงานอย่างไร:

  • echo "$ TEST"

    สิ่งนี้จะใช้ตัวแปรเชลล์ที่เราสนใจและส่งไปยังมาตรฐานออกมา

  • tac

    นี่เป็นการกลับคำสั่งของบรรทัดเพื่อให้บรรทัดสุดท้ายถูกส่งคืนก่อน หลังจากดำเนินการtacแล้วเส้นต่อท้ายจะกลายเป็นเส้นนำ

    (ชื่อtacเป็นสิ่งที่ตรงกันข้ามcatด้วยเหตุผลที่tacทำในสิ่งที่catทำ แต่ตรงกันข้าม)

  • awk 'f==0 && /./ {f=NR} END{if(f==NR){exit 0}; exit 1 }'

    fร้านค้านี้จำนวนเส้นของสายที่ไม่ว่างเปล่าครั้งแรกในตัวแปร หลังจากอ่านทุกบรรทัดมันจะเปรียบเทียบfกับจำนวนบรรทัดNRทั้งหมด ถ้าfเท่ากับNRแล้วเรามีเพียงหนึ่งบรรทัด (ละเว้นช่องว่างเริ่มต้น) และเราออกด้วยรหัส 0 หากมีหนึ่งหรือหลายบรรทัดหลังจากบรรทัดว่างแรกแล้วมันจะออกด้วยรหัส `

  • && echo "Found A Single Line"

    หากawkออกด้วยรหัส 0 echoคำสั่งนั้นจะถูกดำเนินการ

ละเว้นทั้งบรรทัดว่างที่นำหน้าและต่อท้าย

โดยการสร้างawkตัวแปรเพิ่มเติมหนึ่งตัวเราสามารถขยายการทดสอบเพื่อละเว้นทั้งบรรทัดว่างนำหน้าและต่อท้าย:

echo "$TEST" | awk 'first==0 && /./ {first=NR} /./ {last=NR} END{if(first==last){exit 0}; exit 1 }' && echo " Found A Single Line"

เนื่องจากawkรหัสรุ่นนี้รองรับทั้งช่องว่างนำหน้าและช่องว่างท้ายtacจึงไม่ต้องการอีกต่อไป

รับawkรหัสชิ้นในเวลา:

  • first==0 && /./ {first=NR}

    หากตัวแปรfirstนั้นเป็นศูนย์ (หรือยังไม่ได้ตั้งค่า) และบรรทัดนั้นมีตัวละครตัวละครใด ๆ แล้วตั้งfirstเป็นหมายเลขบรรทัด เมื่อawkอ่านบรรทัดเสร็จแล้วfirstจะถูกตั้งค่าเป็นหมายเลขบรรทัดของบรรทัดแรกที่ไม่ว่างเปล่า

  • /./ {last=NR}

    หากบรรทัดมีอักขระใด ๆ อยู่ภายในให้ตั้งค่าตัวแปรlastเป็นหมายเลขบรรทัดปัจจุบัน เมื่อawkอ่านทุกบรรทัดเสร็จแล้วตัวแปรนี้จะมีหมายเลขบรรทัดของบรรทัดที่ไม่ว่างสุดท้าย

  • END{if(first==last){exit 0}; exit 1 }

    การดำเนินการนี้หลังจากอ่านบรรทัดทั้งหมดแล้ว หากfirstมีค่าเท่ากับlastแล้วเราได้เห็นศูนย์หรือโฆษณาที่ไม่ว่างเปล่าเส้นและทางออกด้วยรหัสawk มิฉะนั้นจะออกด้วยรหัส0 1สคริปต์เปลือกสามารถทดสอบโค้ดออกเป็นปกติกับifงบหรือหรือ&&||

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