หากคุณกำลังใช้ Bash คุณไม่จำเป็นต้องใช้grep
:
files="*.jpg"
regex="[0-9]+_([a-z]+)_[0-9a-z]*"
for f in $files # unquoted in order to allow the glob to expand
do
if [[ $f =~ $regex ]]
then
name="${BASH_REMATCH[1]}"
echo "${name}.jpg" # concatenate strings
name="${name}.jpg" # same thing stored in a variable
else
echo "$f doesn't match" >&2 # this could get noisy if there are a lot of non-matching files
fi
done
จะเป็นการดีกว่าถ้าใส่ regex ลงในตัวแปร รูปแบบบางอย่างจะไม่ทำงานถ้ารวมตัวอักษร
วิธีนี้ใช้ =~
ซึ่งเป็นโอเปอเรเตอร์การแข่งขันของ Bash $BASH_REMATCH
ผลที่ได้จากการแข่งขันจะถูกบันทึกไปยังอาร์เรย์ที่เรียกว่า กลุ่มการจับครั้งแรกจะถูกเก็บไว้ในดัชนี 1, ที่สอง (ถ้ามี) ในดัชนี 2, ฯลฯ ดัชนีศูนย์คือการแข่งขันแบบเต็ม
คุณควรทราบว่าไม่มีจุดยึด regex นี้ (และอันที่ใช้grep
) จะตรงกับตัวอย่างใด ๆ ต่อไปนี้และอื่น ๆ ซึ่งอาจไม่ใช่สิ่งที่คุณกำลังมองหา:
123_abc_d4e5
xyz123_abc_d4e5
123_abc_d4e5.xyz
xyz123_abc_d4e5.xyz
หากต้องการกำจัดตัวอย่างที่สองและสี่ให้ทำ regex ของคุณดังนี้:
^[0-9]+_([a-z]+)_[0-9a-z]*
ซึ่งระบุว่าสตริงจะต้องเริ่มต้นด้วยตัวเลขหนึ่งหลักหรือมากกว่า กะรัตหมายถึงจุดเริ่มต้นของสตริง หากคุณเพิ่มเครื่องหมายดอลลาร์ในตอนท้ายของ regex เช่นนี้:
^[0-9]+_([a-z]+)_[0-9a-z]*$
จากนั้นตัวอย่างที่สามจะถูกกำจัดเนื่องจากจุดไม่ได้อยู่ในตัวละครใน regex และเครื่องหมายดอลลาร์แสดงถึงจุดสิ้นสุดของสตริง โปรดทราบว่าตัวอย่างที่สี่ล้มเหลวในการแข่งขันนี้เช่นกัน
หากคุณมี GNU grep
(ประมาณ 2.5 หรือใหม่กว่าฉันคิดว่าเมื่อมี\K
การเพิ่มโอเปอเรเตอร์):
name=$(echo "$f" | grep -Po '(?i)[0-9]+_\K[a-z]+(?=_[0-9a-z]*)').jpg
\K
ประกอบการ (ความยาวตัวแปรมองหลัง) ทำให้เกิดรูปแบบก่อนหน้านี้จะมีการแข่งขัน แต่ไม่รวมถึงการแข่งขันในผลลัพธ์ ความยาวคงที่เท่ากับคือ(?<=)
- รูปแบบจะถูกรวมไว้ในวงเล็บปิด คุณต้องใช้\K
ถ้าปริมาณอาจตรงกับสตริงของความยาวที่แตกต่างกัน (เช่น+
, *
, {2,4}
)
ตัว(?=)
ดำเนินการจับคู่รูปแบบคงที่หรือความยาวผันแปรและเรียกว่า "ดูล่วงหน้า" นอกจากนี้ยังไม่รวมสตริงที่ตรงกันในผลลัพธ์
เพื่อให้ตรงกับตัวพิมพ์เล็กและตัวพิมพ์ใหญ่(?i)
จะใช้ตัวดำเนินการ มันส่งผลต่อรูปแบบที่ตามมาดังนั้นตำแหน่งจึงมีความสำคัญ
อาจต้องปรับ regex ขึ้นอยู่กับว่ามีอักขระอื่น ๆ ในชื่อไฟล์หรือไม่ คุณจะทราบว่าในกรณีนี้ฉันแสดงตัวอย่างของการต่อสตริงในเวลาเดียวกันกับที่จับสตริงย่อย