bash: ทดสอบว่า $ WORD อยู่ในชุดหรือไม่


54

ฉันกำลังมองหาโครงสร้างในbashการตัดสินใจว่าตัวแปร$WORDเป็นหนึ่งในคำที่กำหนด ฉันต้องการสิ่งนี้:

if "$WORD" in dog cat horse ; then 
    echo yes
else
    echo no
fi

ทุบตีมีโครงสร้างเช่นนี้? ถ้าไม่สิ่งที่จะใกล้เคียงที่สุด?

คำตอบ:


57

นี่เป็นโซลูชัน Bash-only (> = เวอร์ชัน 3) ที่ใช้นิพจน์ทั่วไป:

if [[ "$WORD" =~ ^(cat|dog|horse)$ ]]; then
    echo "$WORD is in the list"
else
    echo "$WORD is not in the list"
fi

หากรายการคำของคุณยาวคุณสามารถเก็บไว้ในไฟล์ (หนึ่งคำต่อบรรทัด) และทำสิ่งนี้:

if [[ "$WORD" =~ $(echo ^\($(paste -sd'|' /your/file)\)$) ]]; then
    echo "$WORD is in the list"
else
    echo "$WORD is not in the list"
fi

หนึ่ง caveat ด้วยวิธีการไฟล์:

  • มันจะพังถ้าไฟล์มีช่องว่าง สิ่งนี้สามารถแก้ไขได้โดยบางสิ่งเช่น:

    sed 's/[[:blank:]]//g' /your/file | paste -sd '|' /dev/stdin

ขอขอบคุณที่ @terdon สำหรับการเตือนผมที่จะต้องยึดรูปแบบที่มีและ^$


1
และshopt -s nocasematchอาจช่วยได้หากคุณต้องการให้การค้นหาไม่ตรงตามตัวพิมพ์ใหญ่ - เล็ก
Skippy le Grand Gourou

1
โปรดทราบว่าคุณต้องใช้[[และ]]- [และ]ไม่เพียงพอ
เกร็ก Dubicki

ฉันค้นหา 'oneliner' เพื่อตรวจสอบความถูกต้องของสคริปต์และสิ่งนี้ใช้ได้ผลอย่างสมบูรณ์ ขอขอบคุณ! [[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }
RASG


11

เกี่ยวกับ:

#!/usr/bin/env bash

WORD="$1"
for w in dog cat horse
do
  if [ "$w" == "$WORD" ] 
  then
      yes=1
      break
  fi
done;
[ "$yes" == "1" ] && echo "$WORD is in the list" || 
                     echo "$WORD is not in the list"

แล้ว:

$ a.sh cat
cat is in the list
$ a.sh bob
bob is not in the list

3
if (echo "$set"  | fgrep -q "$WORD")

1
ระวัง แต่นี้จะกลับจริงถ้า$WORDว่างก็จะตรงกับถ้าWORD=caหรือหรือที่คล้ายกันและผมถือว่าคุณหมายWORD=og echo ${set[@]}
terdon

เพียงเพิ่ม -w ลงใน grep เพื่อหลีกเลี่ยงคำบางคำ
BrenoZan

1

คุณสามารถกำหนดฟังก์ชั่นทุบตีสำหรับสิ่งนี้:

function word_valid() 
{ 
  if [ "$1" != "cat" -a "$1" != "dog" -a "$1" != "horse" ];then
    echo no
  else
    echo yes
  fi
}

จากนั้นใช้อย่างนี้:

word_valid cat

1

ฉันกำลังค้นหาวิธีแก้ปัญหา 'หนึ่งบรรทัด' เพื่อตรวจสอบอาร์กิวเมนต์ของสคริปต์ของฉันและใช้คำตอบของโจเซฟอาร์ด้านบนเพื่อหา:

[[ "$ARG" =~ ^(true|false)$ ]] || { echo "Argument received invalid value" ; exit 1 ; }


0

สิ่งนี้ใช้ได้กับฉัน:

#!/bin/bash
phrase=(cat dog parrot cow horse)
findthis=parrot

for item in ${phrase[*]}
do
    test "$item" == "$findthis" && { echo "$findthis found!"; break; }
done

0

คุณอาจต้องการใส่รายการคำลงในไฟล์ในกรณีที่คุณเปลี่ยนรายการบ่อยหรือคุณต้องการที่จะแบ่งปันโดยหลายสคริปต์ และคุณอาจต้องใส่คำลงในไฟล์หากรายการยาวเกินกว่าที่จะจัดการกับสคริปต์ได้ จากนั้นคุณสามารถพูดได้

if fgrep qx "$WORD" word_list

ไม่ฉันไม่ต้องการมีรายชื่ออยู่ในไฟล์
Martin Vegter

0

หากคำต่าง ๆ เป็นรายการที่มีค่าคั่นด้วยการขึ้นบรรทัดใหม่คุณสามารถทำได้:

WORDS="$(ls -1)"
if echo "${WORDS}" | grep --quiet --line-regexp --fixed-strings "${WORD}"; then
    echo yes
else
    echo no
fi

0

คุณสามารถใช้ fgrep เพื่อระบุคำที่อนุญาตทั้งหมด:

if $(echo "$WORD" | fgrep -wq -e dog -e cat -e horse) ; then 
    echo yes
else
    echo no
fi

-wธงตรงกับคำเต็มเท่านั้น-qธงทำให้มันทำงานอย่างเงียบ ๆ (เพราะทั้งหมดที่เราต้องเป็นค่าตอบแทนสำหรับถ้ามีคำสั่งการใช้งาน) และแต่ละ-eรูปแบบการระบุรูปแบบเพื่อให้

fgrepเป็นเวอร์ชันของ grep ที่ใช้จับคู่สตริงปกติแทนการจับคู่ regex หากคุณมีgrepคุณควรมีfgrepแต่ถ้าไม่มันก็เหมือนกับการใช้grepกับ-Fธง (ดังนั้นคุณจะแทนที่fgrep -wqข้างต้นด้วยgrep -Fwq)

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