ความแตกต่างระหว่าง {1,2,3} และ {1..3}


17

มีความแตกต่างระหว่างลำดับ{1,2,3}และ{1..3}?

เช่นถ้าฉันมีไฟล์บางไฟล์

file.1
file.2
file.3

และฉันต้องการให้catพวกเขาเข้าด้วยกันมันปลอดภัยที่จะใช้cat file.{1..3} > file?

สิ่งที่ฉันรู้คือcat file.*>fileอาจทำให้เกิดปัญหาเนื่องจากเชลล์สามารถขยายไฟล์แบบสุ่มในบางครั้ง (ฉันคิดว่ามันขึ้นอยู่กับ inodes ใช่ไหม?)


1
ใช้งานcat file.[123] >file
mikeserv

3
คำสั่งของการขยายตัวของfile.*ไม่ได้ขึ้นอยู่กับ inodes มันเรียงลำดับตามพจนานุกรมเสมอซึ่งอาจขึ้นอยู่กับการตั้งค่าการค้นหาของคุณ
Barmar

1
"ขึ้นอยู่กับ inodes" เสียงเหมือนหนึ่งในฉากที่ "คอมพิวเตอร์" อาชญากร - eqsue วิจัยดีกว่าอาชญากร
Alec Teal

1
@ ไมค์เซอร์ฉันเชื่อว่าฉันเข้าใจ - มันคือ shell glob ดังนั้นมันจึงขยายไปยังไฟล์ที่มีอยู่จริงใช่ไหม? เมื่อเทียบกับ file.{1..3}ซึ่งขยายไปทั้งสามว่ามีอยู่หรือไม่
Wildcard

1
@ Wildcard - ถูกต้องตราบเท่าที่มีอยู่อย่างน้อยหนึ่งรายการนั่นคือ ถ้าไม่ขยายไม่ได้เลยและcatข้อผิดพลาดด้วยfile.[123] not foundหรือสิ่งที่มีประโยชน์มาก
mikeserv

คำตอบ:


18

{1..3} และ {1,2,3}ให้ผลลัพธ์เหมือนกัน แต่ด้วยวิธีที่ต่างกัน

โดยทั่วไป{n1..n2}(ซึ่งมาครั้งแรกจากzsh, bashและkshคัดลอกในภายหลัง) ที่n1และn2มีการผลิตจำนวนเต็มตัวเลขทั้งหมดระหว่างและn1 n2ในขณะที่{x,y,z}การผลิตตัวละครทั้งสามx, yและzและ

ในกรณีของคุณคุณปลอดภัยที่จะใช้ cat file.{1..3} > file

ตอนนี้ในกรณีของcat file.*>fileคุณใช้เชลล์ globbingซึ่งสร้างชื่อไฟล์ทั้งหมดที่เริ่มต้นด้วยfile.และผลจะถูกเรียงลำดับตามลำดับการเรียงในสถานที่ปัจจุบัน

คุณยังปลอดภัยอยู่ แต่ไม่เหลืออีกต่อไปเมื่อคุณมีไฟล์มากกว่า 10 ไฟล์ จะทำให้คุณ{1..10} 1 2 3 4 5 6 7 8 9 10ในขณะที่กำลังโค้งคุณจะได้รับ1 10 2 3 4 5 6 7 8 9


8

ความแตกต่างคือหนึ่งคือรายการและลำดับอื่น ๆ {1,2,3}ขยายไปยังสามองค์ประกอบที่เฉพาะเจาะจง1, และ2 ขยายไปยังรายการตัวเลขระหว่างหนึ่งถึงสาม ในกรณีนี้พวกเขาเหมือนกันและคุณสามารถใช้อย่างใดอย่างหนึ่ง จะขยายไปยังทุกไฟล์และไดเรกทอรีในไดเรกทอรีปัจจุบันที่มีชื่อขึ้นต้นด้วย หากคุณมีเพียง, และจากนั้นที่มากเกินไปจะเทียบเท่ากับอีกสองคน3{1..3}file.*file.file.1file.2file.3

สำหรับปัญหาที่ก่อให้เกิดฉันไม่เห็นว่าทำไม คุณอาจจะคิดถึง

$ cat file.* > file.txt
cat: file.txt: input file is output file

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

$ touch file1 file11 file2
$ echo file*
file1 file11 file2

เพื่อแก้ปัญหานั้นคุณสามารถใช้zshแทนbash(ดูรายละเอียดที่นี่ ):

% echo f*(n)
file1 file2 file11

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


จะไม่มีปัญหา*หากฉันมีมากกว่าหรือเท่ากับ 10 ไฟล์ถ้าฉันขึ้นอยู่กับลำดับที่ถูกต้อง?
syss

1
@ หมายเลข มันจะเป็นปัญหาถ้าคุณมีมากกว่าARG_MAXไฟล์ แต่มันจะเป็นไปได้มากกว่า 10 วิธี
terdon

1
@terdon เขาถูกถามว่าพวกเขาจะปรากฏในลำดับตัวเลข (เช่นไม่ใช่ "1, 10, 2") ไม่ใช่ว่าพวกเขาจะล้นอาร์เรย์อาร์กิวเมนต์
Random832

3
@terdon ฉันคิดว่า @syss ถูกต้องที่ผลลัพธ์ของการcat *กำหนดไม่ดี เอาต์พุตขึ้นอยู่กับเชลล์และสภาพแวดล้อม ดูความคิดเห็นเซบาสเตียน
Marco

จะไม่เพิ่ม.txtแก้ปัญหาด้วยfile.*หรือไม่
Ismael Miguel

6

พวกเขาเหมือนกัน แต่ขึ้นอยู่กับรุ่นทุบตีที่คุณติดตั้งหากมี

จากหน้านี้ :

{xxx,yyy,zzz,...} probably in all bash versions

{a..z} introduced in bash 3

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