เหตุใดสคริปต์นี้จึงไม่ทำงาน


3

ฉันใช้สคริปต์ทุบตีนี้:

for i in $(ls); do mv $i a$i; done

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

for i in $(ls /cygdrive/c/Users/path/to/Images); do mv /cygdrive/c/Users/path/to/Images/$i /cygdrive/c/Users/path/to/Images/a$i; done

มันเติมชื่อไฟล์ด้วยตัวอักษร a แต่ต่อท้ายชื่อไฟล์ด้วยสัญลักษณ์นี้

ความคิดใด ๆ ว่าทำไมมันจะทำเช่นนั้น?

หากมีสิ่งใดช่วยฉันใช้ cygwin ในกล่อง Windows 7

ขอบคุณสำหรับความช่วยเหลือ!


เส้นทางจะเป็น / cygdrive / c / ผู้ใช้ / เส้นทาง / ถึง / รูปภาพเสมอหรือไม่ ถ้าเป็นเช่นนั้นคำนำหน้าจริงที่คุณจะใช้แค่ตัวอักษร 'a' ใช่ไหม เป็นสิ่งที่คุณจะทำงานหลายครั้งหรือเพียงครั้งเดียว? ตัดสินโดยคำสั่งเริ่มต้นของคุณคุณจะทำงานบ่อยครั้ง
UtahJarhead

ใช่ว่าจะเป็นเส้นทาง และใช่คำนำหน้าจริงจะเป็นตัวอักษร 'a' ฉันจะเรียกใช้หลาย ๆ ครั้งต่อวันดังนั้นใช่บ่อยมาก
Devin

ดูความคิดเห็นด้านล่าง (ประมาณ 5 นาที)
UtahJarhead

คำตอบ:


3

ไม่แยกวิเคราะห์ผลลัพธ์ของ 'ls' ทำสิ่งนี้แทน:

for i in *; do mv "$i" "a${i}"; done

เหตุผลคือชื่อไฟล์สามารถมีอักขระเช่น \ r หรือ \ n ในไฟล์เหล่านั้นและการแยกวิเคราะห์ 'ls' จะไม่พบพวกเขา

อัพเดท: ข้อมูลที่เป็นประโยชน์ที่ลิงค์นี้: http://mywiki.wooledge.org/ParsingLs

ด้วยข้อมูลที่เพิ่มข้างต้นจาก OP ให้ใช้สิ่งนี้:

สำหรับ i ใน / cygdrive / c / Users / path / to / Images / *; ทำ mv "$ i" "$ {i% / *} / a $ {i ## * /}"; เสร็จแล้ว

สิ่งนี้จะทำสิ่งหนึ่งที่ไม่ดีอย่างไม่น่าเชื่อ ... มันจะเปลี่ยนชื่อไฟล์ทั้งหมดทุกครั้งที่คุณเรียกใช้ ซึ่งหมายความว่าไฟล์ 'foo' จะเป็น 'afoo' เมื่อคุณเรียกใช้อีกครั้งมันจะเป็น 'aafoo' จากนั้น 'aaafoo' ฯลฯ คุณสามารถเขียนโปรแกรมนี้โดยหลีกเลี่ยงไฟล์ใด ๆ ที่ขึ้นต้นด้วย 'a' แต่จะหลีกเลี่ยงไฟล์ทั้งหมดที่ขึ้นต้นด้วย 'a' แม้ว่าพวกเขาจะไม่ได้ ยังไม่ได้เปลี่ยนชื่อในสคริปต์


ฉันเดาว่าฉันไม่จำเป็นต้องเก็บเส้นทางไว้ในตัวแปร ...
UtahJarhead

ฉันคิดว่ามันจะสมบูรณ์แบบ ฉันกำลังสร้างระบบโง่มากขึ้นหรือน้อยลงซึ่งฉันจะคัดลอกไฟล์ทั้งหมดที่ฉันต้องการลงในโฟลเดอร์รูปภาพเรียกใช้สคริปต์และคัดลอกกลับไปยังโฟลเดอร์ใด ๆ ที่มาจากเดิม แม้ว่าหนึ่งคำถามฉันไม่เข้าใจว่าทำไมต้องใช้ "$ {i% / *} / a $ {i ## * /}" แทนที่จะเป็นเพียง $ i ขอบคุณอีกครั้งสำหรับความช่วยเหลือ!
Devin

เข้าใจ ให้แน่ใจว่าคุณทดสอบ! ตรรกะนั้นดูดีในหัวของฉัน แต่ฉันยังไม่ได้ทดสอบมันเป็นการส่วนตัว สำหรับข้อมูลของคุณอ่านลิงค์นี้: mywiki.wooledge.org/BashFAQ/073 มันอธิบายการขยายพารามิเตอร์ซึ่งเห็นได้ในสคริปต์ของฉันข้างต้นเช่นนี้: "$ {i% / *}" ตัวอย่างเช่นชิ้นส่วนนั้นจะดึง ปิดสิ่งใดหลังจากสุดท้าย / ซึ่งในกรณีนี้เหลือเพียงเส้นทางและไม่ใช่ชื่อไฟล์ เราเพิ่มชื่อไฟล์หลังจากนั้นด้วย "$ {i ## * /}"
UtahJarhead

น่ากลัว ขอบคุณอีกครั้ง. ฉันจะทดสอบสิ่งนี้ก่อน
Devin

1

ทดสอบไดเรกทอรีที่ถูกต้องหรือย้ายไปยังไดเรกทอรีที่ถูกต้อง (หรือทั้งสองอย่าง):

จากที่นี่

E_WRONG_DIRECTORY=73

TargetDirectory=/cygdrive/c/Users/path/to/Images

cd $TargetDirectory
echo "Changing names in $TargetDirectory."

if [ "$PWD" != "$TargetDirectory" ]
then    # Keep from wiping out wrong directory by accident.
  echo "Wrong directory!"
  echo "In $PWD, rather than $TargetDirectory!"
  echo "Bailing out!"
  exit $E_WRONG_DIRECTORY
fi  

เนื่องจากผู้ใช้รายอื่นในสำนักงานของฉันต้องการใช้สคริปต์ของฉันนี่คือสิ่งที่ฉันต้องการในที่สุด ขอบคุณสำหรับคำแนะนำ.
Devin

-2

กรุณาประกาศls /cygdrive/c/Users/path/to/Imagesว่าเป็นตัวแปร กรุณาใช้ตัวแปรเป็นแทน${i} $iยังใช้" "สำหรับเส้นทางของ


2
คุณช่วยอธิบายได้ไหมว่าทำไมถึงเปลี่ยนอะไร
slhck

โปรดหาคำตอบที่อัปเดตของฉัน :-)
San

โพสต์ของคุณจะอธิบายสิ่งต่าง ๆ เกี่ยวกับการทุบตีสคริปต์ไม่ใช่ในการทำงานของสคริปต์ดั้งเดิม
UtahJarhead

โพสต์ของคุณยังแนะนำให้แยกวิเคราะห์ผลลัพธ์ของ 'ls' ให้กับตัวแปรซึ่งรับประกันว่าไม่เพียง แต่จะไม่ได้รับประโยชน์ แต่อาจทำให้เกิดปัญหาเดียวกันกับที่สามารถนำเสนอตัวเองได้แล้ว
UtahJarhead
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.