คุณสามารถทำได้ง่ายพอโดยใช้ตัวเลือก globstar ของ bash (จาก ผู้ชายทุบตี
):
โกลบอลสตาร์
ถ้ากำหนดรูปแบบ **
ใช้ในบริบทการขยายชื่อพาธจะตรงกับไฟล์ทั้งหมดและไดเร็กทอรีและไดเร็กทอรีย่อยเป็นศูนย์หรือมากกว่า ถ้าแบบตามด้วยก /
เฉพาะไดเร็กทอรีและไดเร็กทอรีย่อยเท่านั้นที่ตรงกัน
เนื่องจากเราสามารถใช้ **
ในการค้นหาไฟล์ เราเพียงแค่กำหนดชื่อใหม่โดยรวมถึงชื่อไดเร็กทอรีดั้งเดิมและการเปลี่ยนแปลง .
ถึง _
:
สำหรับไฟล์ใน **/*.txt; ทำ
newName=$(sed 's|[/.]|_|g' <<<"$file" | sed 's/_txt$/.txt/')
cp -- "$file" foo/"$newName"
เสร็จแล้ว
คำอธิบาย
สำหรับไฟล์ใน **/*.txt; ทำ
: ค้นหาไฟล์ทั้งหมด (และไดเร็กทอรี หากเกี่ยวข้อง) ในไดเร็กทอรีปัจจุบันที่มีชื่อลงท้ายด้วย *.txt
.
newName=$(sed 's|[/.]|_|g' <<<"$file" | sed 's/_txt$/.txt/')
: ใช้ เสด
เพื่อแปลงทั้งหมด /
และ .
ถึง _
ในชื่อไฟล์. โปรดทราบว่า $ไฟล์
ที่นี่รวมถึงเส้นทางด้วยดังนั้นมันจะเป็นเช่น case1/0.25/case1.txt
และนั่นกลายเป็น case1_0_25_case1_txt
. จากนั้นเราจะผ่านเอาต์พุตของอันแรก เสด
เป็นครั้งที่สองซึ่งแปลง _txt
(หากพบว่าอยู่ท้ายบรรทัด) ถึง .txt
ให้เรา ``case1_0_25_case1.txt. ผลลัพธ์สุดท้ายจะถูกบันทึกไว้ในตัวแปร
$newName`.
cp -- "$file" foo/"$newName"
: ตอนนี้เราคัดลอกไฟล์ไปยังไดเร็กทอรี ฟู/
และด้วยชื่อใหม่ เดอะ --
ไม่จำเป็นจริงๆ ที่นี่ แต่ให้แน่ใจว่าแนวทางนี้จะใช้ได้กับชื่อไฟล์ใดๆ รวมถึงชื่อที่ขึ้นต้นด้วย a -
.
ฉันสร้างโครงสร้างโฟลเดอร์ที่คุณแสดงในคำถามของคุณใหม่ เรียกใช้คำสั่งด้านบนและได้รับ:
$ ต้นไม้
.
âââ กรณีที่ 1
€ 0.25
ââ â ââ â âââ case1.txt
â âââ 0.30
ââ â ââ â âââ case1.txt
€ 0.35
ââ â ââ â âââ case1.txt
€ 0.45
â âââ case1.txt
âââ กรณีที่ 2
€ 0.25
ââ â ââ â âââ case2.txt
â âââ 0.30
ââ â ââ â âââ case2.txt
€ 0.35
ââ â ââ â âââ case2.txt
€ 0.45
â âââ case2.txt
âââ ฟู
âââ case1_0_25_case1.txt
âââ case1_0_30_case1.txt
âââ case1_0_35_case1.txt
âââ case1_0_45_case1.txt
âââ case2_0_25_case2.txt
âââ case2_0_30_case2.txt
âââ case2_0_35_case2.txt
âââ case2_0_45_case2.txt
11 ไดเร็กทอรี 16 ไฟล์