วงเล็บปีกกา 'Binding'


3

ใน Bash

echo a{b,c}d{e,f}

พิมพ์

abde    abdf    acde    acdf

ผลลัพธ์ที่ฉันต้องการดูคือ

abde    acdf

กล่าวอีกนัยหนึ่งเมื่อได้รับพารามิเตอร์Nฉันต้องการให้ Bash ใช้พารามิเตอร์i th ภายในวงเล็บปีกกาแต่ละคู่เพื่อสร้างสตริงN


Nคือจำนวนอาร์กิวเมนต์ระหว่างวงเล็บปีกกา
Isaac Kleinman

เขียนเป็น{bde,cdf}ไม่ใช่ตัวเลือก? ถ้าอย่างนั้นคุณอาจจะมีอาร์เรย์ลูปและการทำดัชนีหรืออะไรทำนองนั้น
frostschutz

ที่จริงแล้วคำสั่งเหล่านี้เป็นคำสั่งสองแบบที่ฉันหวังว่าจะผสาน: git rm src/test/java/org/sonatype/mavenbook/AppTest.javaและgit rm src/main/java/org/sonatype/mavenbook/App.java
Isaac Kleinman

เครื่องมือจัดฟันเพียงควบคุมเอาท์พุท พวกเขาไม่ใช่ตัวแทน ตามที่ Frostschutz แนะนำสิ่งที่คุณถามคือa{bde,cdf}- สองตอนจบที่แตกต่างกันซึ่งมีตัวอักษรกลางเหมือนกัน หากทั้งสองไฟล์เป็นไฟล์ที่มีอยู่คุณสามารถพูดa[bc]d[ef]ได้ แต่นั่นเป็นการสรุปการขยายชื่อไฟล์และการมีอยู่ของไฟล์ (โดยไม่มีacdeหรือabdf) echo abde acdfคุณสามารถได้อย่างง่ายดายเพียงแค่ ให้ข้อมูลเพิ่มเติมกับเรา มิฉะนั้นนี่เป็นเพียง "ฉันหวังว่ามันจะทำงานแบบนี้" ซึ่งมันไม่แน่นอน
พอลฮอดจ์ส

คำตอบ:


3

ฉันจะทำกับอาร์เรย์:

$ foo=( b c ); bar=( e f ); for i in {0..1}; do echo a${foo[$i]}d${bar[$i]}; done
abde
acdf

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

foo=( b c ); bar=( e f ); for i in $(seq 0 $((${#foo[@]}-1))); do 
   echo a${foo[$i]}d${bar[$i]}; 
done

0

นี่เป็นคำตอบที่งี่เง่า แต่นี่มันคือ:

$ echo a{b,c,d}e{f,g,h} | awk 'BEGIN {N=3;} { for (i=0; i<N; i++) { print $(i*N+i+1) } }'

$ echo a{b,c,d,1}e{f,g,h,2} | awk 'BEGIN {N=4;} { for (i=0; i<N; i++) { print $(i*N+i+1) } }'

$ echo a{b,c,d,1,A}e{f,g,h,2,Z} | awk 'BEGIN {N=5;} { for (i=0; i<N; i++) { print $(i*N+i+1) } }'

0

คุณไม่สามารถเปลี่ยนวิธีการทำงานของเครื่องมือจัดฟัน

หากมีสตริงที่ไม่ปรากฏในข้อความให้บอก,คุณสามารถใช้การแทนที่สตริงที่ต่อเนื่องกับอาร์เรย์:

a=(,b,e @c,f)
a=("${a[@]/,/a/}")
a=("${a[@]/,/d}")
echo "${a[@]}"

การวนซ้ำจะชัดเจนขึ้น หากคุณต้องการติดชิ้นส่วนเข้าด้วยกันคุณสามารถใช้ตัวคั่นที่ไม่ปรากฏในสตริงบอกว่า,จะต้องใช้เครื่องหมายวงเล็บพิเศษในกรณีใด

a=(); IFS=,; set -f
for x in b,e c,f; do
  a+=(a${x%*,}d${x#*,})
done

อีกวิธีหนึ่งคือการกำหนดสองอาร์เรย์ขนาน

version=(test main)
files=(AppTest.java App.java)
for ((i=0; i<${#files}; i++) rm "src/$version[i]/java/org/sonatype/mavenbook/files[i].java"

ฉันคิดว่าวิธีที่ง่ายที่สุดในการจัดการกับคำสั่งเฉพาะนี้คือการกำหนดฟังก์ชั่น

rmapp () { rm "src/$1/java/org/sonatype/mavenbook/$2.java"; }

1
ฉันคิดว่าฟังก์ชั่นเป็นทางออกที่สะอาดที่สุด ลูปทั้งหมดนั้นดูน่าเกลียด (ซึ่งเป็นเหตุผลว่าทำไมฉันไม่สามารถเอาชนะคำตอบทั้งหมดนี้ได้)
Ian D. Allen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.