ก่อนหน้านี้ฉันมีคำตอบที่น่าอาย แต่คำตอบของเดนิสทำให้ฉันนึกถึงว่าฉันพลาดสิ่งพื้นฐานที่สุดไปแล้ว ดังนั้นฉันจึงลบคำตอบดั้งเดิมของฉัน แต่เนื่องจากไม่มีใครพูดสิ่งพื้นฐานนี้มากฉันคิดว่ามันคุ้มค่าที่จะวางไว้ที่นี่
คำถามเดิมคือ "ฉันมีไฟล์ข้อความที่มีรายชื่อไฟล์ที่คั่นด้วยช่องว่างฉันจะคัดลอกไฟล์เหล่านั้นไปยังไดเรกทอรีเป้าหมายเดียวได้อย่างไร" ในตอนแรกสิ่งนี้อาจดูยุ่งยากหรือซับซ้อนเนื่องจากคุณคิดว่าคุณจะต้องแยกรายการออกจากไฟล์ในลักษณะเฉพาะ แต่เมื่อเปลือกกระบวนการบรรทัดคำสั่ง, สิ่งแรกที่มันไม่สามารถแยกรายการอาร์กิวเมนต์ลงในราชสกุลและ (ที่นี่ใครบิตได้กล่าวทันที) พื้นที่แยกราชสกุล (ขึ้นบรรทัดใหม่ยังแยกโทเค็นซึ่งเป็นสาเหตุให้การทดสอบของดั๊กแฮร์ริสด้วยรายการที่คั่นด้วยบรรทัดใหม่มีผลลัพธ์เหมือนกัน) นั่นคือเชลล์คาดหวังและสามารถจัดการรายการคั่นด้วยช่องว่างได้แล้ว
ดังนั้นสิ่งที่คุณต้องทำที่นี่คือใส่รายการที่คั่นด้วยช่องว่าง (ที่คุณมี) ในสถานที่ที่เหมาะสมในคำสั่งของคุณ คำสั่งของคุณเป็นรูปแบบบางอย่างนี้:
cp file1 file2 file3...file# target
รอยย่นเพียงอย่างเดียวคือคุณต้องการรับรายการไฟล์ 1 ถึง # จากไฟล์ข้อความของคุณ
เมื่อเดนนิสชี้ให้เห็นในความคิดเห็นของเขาความพยายามเริ่มต้นของคุณ ( cp
cat list.txt new_folder
) ควรจะใช้งานได้แล้ว ทำไม? เนื่องจากคำสั่งภายในcat list.txt
ถูกประมวลผลก่อนโดยเชลล์และขยายเข้าไปfile1 file2 file3...file#
ซึ่งเป็นสิ่งที่เชลล์ต้องการและต้องการที่ส่วนคำสั่งนั้น ถ้ามันไม่ทำงาน (1) คุณมีการพิมพ์ผิดหรือ (2) ชื่อไฟล์ของคุณแปลกไปอย่างใดอย่างหนึ่ง (มีช่องว่างหรือตัวอักษรผิดปกติอื่น ๆ )
เหตุผลที่คำตอบทั้งหมดของ Dennis นั้นเป็นเพียงการให้รายชื่อไฟล์ที่จำเป็นสำหรับcp
การทำงานโดยวางรายการนั้นไว้ในคำสั่งทั้งหมด อีกครั้งคำสั่งนี้อยู่ในโครงสร้าง:
cp list-of-files target_directory
มันง่ายที่จะดูว่าทั้งหมดนี้มารวมกันในรุ่นนี้ได้อย่างไร:
cp $(<list.txt) new_folder
$()
ทำให้เชลล์รันคำสั่งภายในวงเล็บจากนั้นแทนที่เอาต์พุตที่จุดนั้นในบรรทัดที่ใหญ่กว่า จากนั้นเชลล์จะรันบรรทัดโดยรวม โดยวิธีการที่$()
เป็นรุ่นที่ทันสมัยมากขึ้นของสิ่งที่คุณกำลังทำอยู่แล้วกับ backticks ( `) ถัดไป: <
เป็นตัวดำเนินการเปลี่ยนเส้นทางไฟล์ มันบอกเชลล์ให้ดัมพ์เนื้อหาของlist.txt
ไปยังอินพุตมาตรฐาน เนื่องจาก$()
บิตได้รับการประมวลผลก่อนนี่คือสิ่งที่เกิดขึ้นในขั้นตอน:
cp $(<list.txt) new_folder
# split line into three tokens: cp, $(<list.txt), new_folder
cp file1 file2 file3...file# new_folder
# substitute result of $(<list.txt) into the larger command
เห็นได้ชัดว่าขั้นตอนที่ 2 เป็นเพียงcp
คำสั่งปกติที่คุณต้องการ
ฉันรู้ว่าฉันกำลังตีม้าตัวนี้ (อาจตายมาก) แต่ฉันคิดว่ามันคุ้มค่าที่จะทำ การเข้าใจอย่างถ่องแท้ถึงวิธีที่เชลล์ประมวลผลคำสั่งสามารถช่วยคุณเขียนได้ดีขึ้นและทำให้ง่ายขึ้นมาก นอกจากนี้ยังจะแสดงให้คุณเห็นว่าปัญหาที่อาจซ่อนอยู่ ในกรณีนี้คำถามแรกของฉันที่คุณควรมีเกี่ยวกับชื่อไฟล์ตลกหรือตัวพิมพ์ที่เป็นไปได้ ไม่จำเป็นต้องแสดงผาดโผน