แปลง symlink เป็นฮาร์ดลิงก์


25

ฉันต้องการแปลงซอฟต์ลิงค์ซ้ำเป็นฮาร์ดลิงก์ในไดเรกทอรีซ้ำ ๆ ฉันลองทำสิ่งนี้แล้ว:

for f in *; do (mv $f{,~} && ln $(readlink $f~) && rm $f~) done

… แต่มันมีปัญหาสำคัญสองประการ:

  • ไม่เกิดซ้ำ
  • เลือกไฟล์ที่ไม่ใช่ลิงก์สัญลักษณ์

มันจะดีถ้าได้รับบรรทัดข้างต้นfind -type lแต่ฉันไม่แน่ใจว่าจะทำอย่างไร


1
ดูเพิ่มเติม [การสนทนานี้] [1] ( cp -aH) [1]: unix.stackexchange.com/questions/94185/…
Michael Shigorin

คำตอบ:


34

คำสั่งนี้จะทำงาน:

find -type l -exec bash -c 'ln -f "$(readlink -m "$0")" "$0"' {} \;

มันทำงานอย่างไร:

  • find -type l ค้นหาลิงก์ทั้งหมดในไดเรกทอรีปัจจุบัน

  • -exec bash -c '...' {} \;...จะเรียกทุบตีในการดำเนินการ

    มันผ่านไป{}- ชื่อของการเชื่อมโยงที่กำลังถูกแปรรูป - $0เป็นอาร์กิวเมนต์ซึ่งทุบตีสามารถเข้าถึงเป็น

  • readlink -m "$0" ส่งคืนพา ธ สัมบูรณ์ของปลายทางของลิงก์สัญลักษณ์

  • ln -f "$(readlink -m "$0")" "$0"เขียนทับ ( -f) ลิงก์สัญลักษณ์ที่$0มีฮาร์ดลิงก์ไปยังเป้าหมาย

หากลิงก์ไม่สามารถแปลงได้ด้วยเหตุผลบางอย่างลิงก์นั้นจะยังคงไม่ถูกแตะต้องและ ln จะพิมพ์ข้อความแสดงข้อผิดพลาด


สำหรับย่อหน้าสุดท้ายนั้นจะไม่เพียงพอหรือไม่ที่จะระบุพา ธ สัมบูรณ์ไปที่bashและln?
Daniel Beck

2
ปัญหาของฉันคือreadlink ที่ส่งกลับเส้นทางสัมพัทธ์โดยค่าเริ่มต้น แต่-eสวิตช์แก้ไขที่
Dennis

สิ่งที่จะเป็นคำสั่งสำหรับ OSX?
Igor Markelov

@IgorMarkelov ฉันขอโทษ แต่ฉันไม่มีเงื่อนงำเมื่อพูดถึง OSX
Dennis

1
บน Mac มันคือและbrew install coreutils find * -type l -exec bash -c 'ln -f "$(greadlink -m "$0")" "$0"' {} \;
Igor Markelov
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.