সদৃশ ফাইলগুলি সন্ধান এবং সিমলিঙ্কগুলির সাথে তাদের প্রতিস্থাপন


16

আমি সদৃশ ফাইল (এমনকি বিভিন্ন নাম সহ) জন্য একটি প্রদত্ত ডিরেক্টরি ভিতরে পরীক্ষা করার উপায় খুঁজে বার করার চেষ্টা করছি এবং প্রথম উপস্থিতির দিকে ইঙ্গিত করে সিমলিঙ্কগুলি দিয়ে তাদের প্রতিস্থাপন করব। আমি চেষ্টা করেছি fdupesকিন্তু এটি কেবল সেই অনুলিপিগুলি তালিকাভুক্ত করে।
এটি প্রসঙ্গে: আমি আমার পছন্দ অনুসারে একটি আইকন থিম কাস্টমাইজ করছি এবং আমি দেখতে পেয়েছি যে অনেকগুলি আইকন, তাদের পিতামাতার ফোল্ডারের ভিতরে বিভিন্ন নাম এবং বিভিন্ন অবস্থান রয়েছে, এবং বিভিন্ন উদ্দেশ্যে ব্যবহৃত হয়, মূলত কেবল একই ছবি। যেহেতু কেবলমাত্র একটি সত্যই প্রয়োজন হয় যখন বিশ বা ত্রিশবার একই পরিবর্তন প্রয়োগ করা বাড়াবাড়ি হয়, আমি কেবল একটি চিত্র রাখতে এবং অন্য সমস্তকে সিমলিংক করতে চাই।

উদাহরণস্বরূপ, আমি যদি fdupes -r ./ডিরেক্টরিটির ভিতরে চলে যাই তবে testdirএটি আমার কাছে নিম্নলিখিত ফলাফলগুলি ফিরে আসতে পারে:

./file1.png
./file2.png
./subdir1/anotherfile.png
./subdir1/subdir2/yetanotherfile.png

এই আউটপুটটি দেওয়া হয়েছে, আমি file1.pngসমস্ত ফাইলের নাম বজায় রেখে কেবল ফাইলটিই রাখতে চাইছি , সমস্ত অন্য মুছে ফেলতে এবং এটিকে নির্দেশ করে সিমলিংকগুলি দিয়ে প্রতিস্থাপন করতে চাই। সুতরাং file2.pngএটির নামটি ধরে রাখবে, তবে file1.pngসদৃশ হওয়ার পরিবর্তে একটি লিঙ্ক হয়ে যাবে ।

এই লিঙ্কগুলি একটি নিখুঁত পথে নির্দেশ করা উচিত নয়, তবে পিতামাতার testdirডিরেক্টরিতে আপেক্ষিক হওয়া উচিত ; অর্থাত্ yetanotherfile.pngপয়েন্ট হবে ../../file1.png, না/home/testuser/.icons/testdir/file1.png

আমি জিওআই এবং সিআইএল জড়িত এমন সমাধানগুলিতে উভয়ই আগ্রহী। fdupesআমি এটিকে উদ্ধৃত করে ব্যবহার করা বাধ্যতামূলক নয় কারণ এটি আমার জানা সরঞ্জাম, তবে আমি অন্যান্য সরঞ্জামগুলিও সলিউশনের জন্য উন্মুক্ত।

আমি নিশ্চিত যে এই সমস্ত পরিচালনা করার জন্য একটি ব্যাশ স্ক্রিপ্টটি তৈরি করা এতটা কঠিন হওয়া উচিত নয়, তবে আমি কীভাবে এটি লিখতে হবে তা খুঁজে পাওয়ার জন্য আমি যথেষ্ট বিশেষজ্ঞ নই।

উত্তর:


3

প্রথম; আপনার সাধারণত সিডলিঙ্কগুলি ব্যবহার করার দরকার আছে, সাধারণ হার্ডলিঙ্কগুলি নয়? আপেক্ষিক পাথ সহ সিমলিংকের প্রয়োজনীয়তা বোঝার জন্য আমার খুব কষ্ট হচ্ছে। আমি এই সমস্যাটি কীভাবে সমাধান করব তা এখানে:

আমি মনে করি fdupes এর দেবিয়ান (উবুন্টু) সংস্করণটি -Lবিকল্প ব্যবহার করে হার্ড লিঙ্কগুলির সাথে সদৃশগুলি প্রতিস্থাপন করতে পারে , তবে এটি যাচাই করার জন্য আমার কাছে ডেবিয়ান ইনস্টলেশন নেই।

-Lবিকল্পের সাথে যদি আপনার কোনও সংস্করণ না থাকে তবে আপনি কমান্ডলাইনফুতে পাওয়া এই ক্ষুদ্র বাশ স্ক্রিপ্টটি ব্যবহার করতে পারেন ।
মনে রাখবেন যে এই বাক্য গঠনটি কেবল ব্যাশে কাজ করবে।

fdupes -r -1 path | while read line; do master=""; for file in ${line[*]}; do if [ "x${master}" == "x" ]; then master=$file; else ln -f "${master}" "${file}"; fi; done; done

উপরের কমান্ডটি সমস্ত ডুপ্লিকেট ফাইলগুলিকে "পাথ" এ সন্ধান করবে এবং হার্ডলিঙ্কগুলি দিয়ে প্রতিস্থাপন করবে। আপনি ls -ilRইনোড নম্বরটি চালিয়ে এবং দেখে এটি যাচাই করতে পারেন । এখানে দশটি অভিন্ন ফাইল সহ একটি সামিল রয়েছে:

$ ls -ilR

total 20
3094308 -rw------- 1 username group  5 Sep 14 17:21 file
3094311 -rw------- 1 username group  5 Sep 14 17:21 file2
3094312 -rw------- 1 username group  5 Sep 14 17:21 file3
3094313 -rw------- 1 username group  5 Sep 14 17:21 file4
3094314 -rw------- 1 username group  5 Sep 14 17:21 file5
3094315 drwx------ 1 username group 48 Sep 14 17:22 subdirectory

./subdirectory:
total 20
3094316 -rw------- 1 username group 5 Sep 14 17:22 file
3094332 -rw------- 1 username group 5 Sep 14 17:22 file2
3094345 -rw------- 1 username group 5 Sep 14 17:22 file3
3094346 -rw------- 1 username group 5 Sep 14 17:22 file4
3094347 -rw------- 1 username group 5 Sep 14 17:22 file5

সমস্ত ফাইলের আলাদা আলাদা ইনোড নম্বর থাকে, এগুলি পৃথক ফাইল করে। এখন সেগুলি প্রতিলিপি দিন:

$ fdupes -r -1 . | while read line; do j="0"; for file in ${line[*]}; do if [ "$j" == "0" ]; then j="1"; else ln -f ${line// .*/} $file; fi; done; done
$ ls -ilR
.:
total 20
3094308 -rw------- 10 username group  5 Sep 14 17:21 file
3094308 -rw------- 10 username group  5 Sep 14 17:21 file2
3094308 -rw------- 10 username group  5 Sep 14 17:21 file3
3094308 -rw------- 10 username group  5 Sep 14 17:21 file4
3094308 -rw------- 10 username group  5 Sep 14 17:21 file5
3094315 drwx------  1 username group 48 Sep 14 17:24 subdirectory

./subdirectory:
total 20
3094308 -rw------- 10 username group 5 Sep 14 17:21 file
3094308 -rw------- 10 username group 5 Sep 14 17:21 file2
3094308 -rw------- 10 username group 5 Sep 14 17:21 file3
3094308 -rw------- 10 username group 5 Sep 14 17:21 file4
3094308 -rw------- 10 username group 5 Sep 14 17:21 file5

ফাইলগুলিতে এখন একই ধরণের ইনোড নম্বর রয়েছে যার অর্থ তারা সমস্ত ডিস্কে একই শারীরিক ডেটার দিকে নির্দেশ করে।

আমি আশা করি এটি আপনার সমস্যার সমাধান করে বা কমপক্ষে আপনাকে সঠিক দিকে নির্দেশ করে!


আমি স্মরণ fdupes লিঙ্ক, @arnefm সঙ্গে dupes প্রতিস্থাপন করার জন্য একটি বিকল্প না থাকার কিন্তু আমি কিছু দেখতে পাচ্ছি না মানুষ না এটা একটি বিকল্প হয় v1.51(উবুন্টু 14.04.2 LTS)।
অ্যালাস্টার

আমার কাঁটাচামচ jdupesgithub.com/jbruchon/jdupes হয়েছে -Lযা ডুপ্লিকেট সেট আকাঙ্ক্ষিত হার্ড লিঙ্ক আছে বিকল্প।
জোডি লি ব্রুচন

আমি এখানে স্ক্রিপ্টটি টুইট করেছি। এটি এখনও স্পেসগুলি পরিচালনা করবে না, তবে অন্যান্য বিশেষ অক্ষরগুলি হ্যান্ডেল করবে (আমার কাছে ফাইলগুলিতে ইউআরএল কোয়েরি স্ট্রিং ছিল)। এছাড়াও, ${line//…/}অংশটি আমার পক্ষে কাজ করছে না, তাই হার্ডলিঙ্কে প্রথম "মাস্টার" ফাইলটি পাওয়ার জন্য আমি একটি ক্লিনার উপায়ে করেছি।
আইবিবোর্ড

1
আমরা যদি rsyncঅন্য ধরণের ফাইল সিস্টেমে ব্যবহার করি তবে আমাদের কি আপেক্ষিক সফটলিঙ্কগুলি দরকার ? অথবা যদি ফাইল সিস্টেমটি স্তরক্রম সংরক্ষণ করে না, যেমন এটি একটি ব্যাকআপ সার্ভার যা সমস্ত কিছুকে আওতায় রাখে /«machine-name»/...? বা ব্যাকআপ থেকে পুনরুদ্ধার করতে চান? হার্ডলিঙ্কগুলি এখানে কীভাবে সংরক্ষণ করা হবে তা আমি দেখতে পাচ্ছি না। আপেক্ষিক সফটলিঙ্কগুলির বেঁচে থাকার আরও ভাল সুযোগ থাকবে, আমি ভাবতে পারি।
বুডি

6

আপনি যদি খুব স্ক্রিপ্টিং পছন্দ করেন না তবে আমি আরডিফাইন্ডের সুপারিশ করতে পারি । যা সদৃশ ফাইলগুলির জন্য প্রদত্ত ডিরেক্টরিগুলি স্ক্যান করে এবং তা শক্ত-বা নরম লিঙ্কযুক্ত একসাথে করবে। আমি এটিকে আমার রুবি রত্ন ডিরেক্টরিটি দুর্দান্ত সাফল্যের সাথে নকল করার জন্য ব্যবহার করেছি। এটি ডেবিয়ান / উবুন্টুতে উপলব্ধ।


4

আমারও একই অবস্থা ছিল, তবে আমার ক্ষেত্রে প্রতীকী লিঙ্কটি একটি আপেক্ষিক পথের দিকে নির্দেশ করা উচিত তাই আমি কৌশলটি করতে এই অজগর লিপিটি লিখেছিলাম :

#!/usr/bin/env python
# Reads fdupes(-r -1) output and create relative symbolic links for each duplicate
# usage: fdupes -r1 . | ./lndupes.py

import os
from os.path import dirname, relpath, basename, join
import sys

lines = sys.stdin.readlines()

for line in lines:
    files = line.strip().split(' ')
    first = files[0]
    print "First: %s "% first
    for dup in files[1:]:
        rel = os.path.relpath(dirname(first), dirname(dup))
        print "Linking duplicate: %s to %s" % (dup, join(rel,basename(first)))
        os.unlink(dup)
        os.symlink(join(rel,basename(first)), dup)

প্রতিটি ইনপুট লাইনের (যা ফাইলগুলির একটি তালিকা) এর জন্য স্ক্রিপ্ট ফাইল তালিকাটি বিভক্ত করে তোলে (হোয়াইটস্পেস বিচ্ছিন্ন), প্রতিটি ফাইল থেকে প্রথম একটিতে আপেক্ষিক পথ পায় এবং তারপরে সিমলিংক তৈরি করে।


1

সুতরাং, আর্নেফের দেওয়া উত্তর (যা পুরো ইন্টারনেট জুড়েই অনুলিপি করা হয়েছে) ফাইলের নামের ফাঁকা জায়গাগুলি নিয়ে কাজ করে না। আমি একটি স্ক্রিপ্ট লিখেছি যা ফাইলগুলির ফাঁকা জায়গাগুলি নিয়ে কাজ করে।

#!/bin/bash
fdupes -r -1 CHANGE_THIS_PATH | sed -e 's/\(\w\) /\1|/g' -e 's/|$//' > files
while read line; do
        IFS='|' read -a arr <<< "$line"
        orig=${arr[0]}
        for ((i = 1; i < ${#arr[@]}; i++)); do
                file="${arr[$i]}"
                ln -sf "$orig" "$file"
        done 
done < files

এটি যা করে তা হ'ল ডুপগুলি খুঁজে বের করে এবং তাদের পিআইপিই 'ফাইল' নামের একটি ফাইলে আলাদা করে লিখুন।

তারপরে এটি ফাইলটিকে একটি লাইনে এক এক করে লাইনে পাঠায় এবং অ্যারের প্রতিটি উপাদান পিআইপিই দ্বারা সীমিত করে দেওয়া হয়।

এরপরে এটি অ্যারের সমস্ত অ-প্রথম উপাদানগুলিতে পুনরাবৃত্তি করে, ফাইলটি প্রথম উপাদানটিতে একটি সিমলিংক দিয়ে প্রতিস্থাপন করে।

বাহ্যিক ফাইল ('ফাইল') অপসারণ করা যেতে পারে, যদি fdupes কমান্ডটি একটি সাব-শেলের মধ্যে কার্যকর করা হয়, যা সরাসরি সরাসরি পড়ে থাকে, তবে এই উপায়টি আরও স্পষ্ট মনে হয়।


2
এই সংস্করণটি কোনও পাইপযুক্ত নামের ফাইলগুলির সাথে ডিল করে? আমি ধরে নিই যে কোনও সংস্করণই নতুন লাইনের সমন্বিত ফাইলের নামগুলি পরিচালনা করে না, তবে এটি অন্য কোনও কিছুর চেয়ে fdupes এর সীমাবদ্ধতা।
ধাগ

এটি হয় না, তবে আপনি যা চান আইএফএস সেট করতে পারেন (সেড প্রতিস্থাপনের মানটিও সংশোধন করুন), তবে আপনার কোনও সমস্যা (আইএফএস থেকে 'ñ' বা এমন কিছু কাজ করা উচিত নয়) হওয়া উচিত
ডেভিড ভেন্টুরা

এটি ভাঙা সিমলিংকগুলি তৈরি করে এবং আমার নিজের সাথে ফাইল যুক্ত রয়েছে। ব্যবহার করবেন না
মিস্টারমিজিজ 25:37

0

কিছু সামনের দিকে এগিয়ে:

  • বেস নির্দিষ্ট
  • ফাইলের নামে কোনও স্থান নেই
  • ধরে নিই প্রতিটি লাইনে সর্বাধিক 2 টি ফাইল রয়েছে।

fdupes -1r common/base/dir | while read -r -a line ; do ln -sf $(realpath --relative-to ${line[1]} ${line[0]}) ${line[1]}; done

যদি প্রতিটি জোড়ের জন্য আমাদের একটি সিলেট লিঙ্ক তৈরি করা প্রয়োজন তার চেয়ে 2 টিরও বেশি ফাইলগুলি নকল হয় (যেমন ফাইল 1 ফাইল 2 ফাইল 3) - ফাইল 1, ফাইল 2 এবং ফাইল 1, ফাইল 3 কে 2 পৃথক কেস হিসাবে বিবেচনা করুন:

if [[ ${#line[@]} -gt 2 ]] ;then 
  ln -sf $(realpath --relative-to ${line[1]} ${line[0]}) ${line[1]} 
  ln -sf $(realpath --relative-to ${line[2]} ${line[0]}) ${line[2]} 
  ...
fi

প্রতি লাইনে একটি স্বেচ্ছাসেবী সংখ্যার সদৃশ পরিচালনা করার জন্য এটি ব্যয় করতে আরও কিছুটা প্রচেষ্টা লাগবে।

আরেকটি পদ্ধতি হ'ল প্রথমে পরম পাথগুলিতে প্রতিলিপি তৈরি করা, তারপরে তাদের রূপান্তর করুন:

fdupes -1r /absolute/path/common/base/dir | while read -r -a line ; do ln -sf ${line[0]} ${line[1]}; done
chroot /absolute/path/common/base/dir ; symlinks -cr .

এটি @ গিলিসের উত্তরের ভিত্তিতে: /unix//a/100955/77319

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.