رسينك --حذف --ملفات=قائمة / دست/ لا حذف الملفات غير المرغوب فيها

StackOverflow https://stackoverflow.com/questions/1813907

  •  06-07-2019
  •  | 
  •  

سؤال

كما ترون في العنوان أنا في محاولة مزامنة مجلد مع قائمة من الملفات.تمنيت أن هذا الأمر من شأنه أن حذف كافة الملفات في دست/ التي ليست في القائمة ، لكنه لم يفعل.

لذا بحثت قليلا و نعرف الآن أن رسينك لا يمكن أن تفعل هذا.

ولكن أنا في حاجة إليها ، لذلك هل تعرف أي طريقة للقيام بذلك ؟

PS:القائمة التي تم إنشاؤها بواسطة البرنامج النصي الثعبان ، لذلك لا يمكن تصورها أن الحل الخاص بك يستخدم بعض كود بايثون.

تحرير, دعونا نكون الخرسانة:

قائمة تبدو مثل هذا:

/home/max/Musik/Coldplay/Parachutes/Trouble.mp3
/home/max/Musik/Coldplay/Parachutes/Yellow.mp3
/home/max/Musik/Coldplay/A Rush of Blood to the Head/Warning Sign.mp3
/home/max/Musik/Coldplay/A Rush of B-Sides to Your Head/Help Is Around the Corner.mp3
/home/max/Musik/Coldplay/B-Sides (disc 3)/Bigger Stronger.mp3

و الأمر من هذا القبيل:

rsync --delete --files-from=/tmp/list / /home/max/Desktop/foobar/

يعمل هذا, ولكن إذا قمت بحذف الخط لا يتم حذف في foobar/.

تحرير 2:

rsync -r --include-from=/tmp/list --exclude=* --delete-excluded / /home/max/Desktop/foobar/

الذي يعمل لا ...

هل كانت مفيدة؟

المحلول

ربما يمكنك القيام بذلك باستخدام قائمة تشمل أنماط بدلا من استخدام --delete-excluded (الذي لا كما يوحي الاسم)?شيء من هذا القبيل:

rsync -r --include-from=<patternlistfile> --exclude=* --delete-excluded / dest/

إذا أسماء الملفات من المرجح أن تحتوي على أحرف البدل (*, ? و [) ثم قد تحتاج إلى تعديل الثعبان إلى الهروب منها:

re.sub("([[*?])", r"\\\1", "abc[def*ghi?klm")

تحرير: القائمة على نمط مطابقة يعمل بشكل مختلف قليلا --files-from في هذا rsync لن recurse إلى الدلائل التي تتطابق مع استبعاد نمط لأسباب من الكفاءة.حتى إذا كان لديك ملفات في /some/dir و /some/other/dir ثم نمط الملف يحتاج إلى تبدو مثل:

/some/
/some/dir/
/some/dir/file1
/some/dir/file2
/some/other/
/some/other/dir/
/some/other/dir/file3
...

بدلا من ذلك, إذا كانت جميع الملفات في نفس الدليل حيث يمكنك كتابة الأمر قليلا:

rsync -r --include-from=<patternlistfile> --exclude=* --delete-excluded /some/dir/ dest/

ثم أنماط الخاص بك تصبح:

/file1
/file2

تحرير: التفكير حول هذا الموضوع ، يمكن أن تشمل جميع الدلائل مع نمط واحد:

/**/

ولكن بعد ذلك كنت في نهاية المطاف مع الدليل بالكامل شجرة في dest/ والتي ربما ليس ما تريد.ولكن الجمع بين ذلك مع -m (الذي الخوخ الدلائل الفارغة) يجب حل هذا - لذا فإن الأمر ينتهي شيئا مثل:

rsync -m -r --delete-excluded --include-from=<patternfile> --exclude=* / dest/

و نمط الملف:

/**/
/some/dir/file1
/some/other/dir/file3

نصائح أخرى

وهذا ليس بالضبط الحل، ولكن الناس يأتون إلى هنا قد تجد هذه المفيد: منذ رسينك 3.1.0 هناك معلمة --delete-missing-args الذي حذف الملفات في الدليل الوجهة عند مزامنة دليلين باستخدام --files-from. سوف تحتاج إلى تحديد الملفات المحذوفة في /tmp/list جنبا إلى جنب مع الملفات التي لا تريد نسخها:

rsync --delete-missing-args --files-from=/tmp/list /source/dir /destination/dir

الصفحة رجل للحصول على مزيد من التفاصيل.

وكما أوضح، الأمر

rsync -r --delete --files-from=$FILELIST user@server:/ $DEST/

لا تقم بحذف المحتوى في الوجهة عندما تمت إزالة إدخال من $ FILELIST. وهناك حل بسيط هو استخدام بدلا من ذلك ما يلي:

mkdir -p $DEST
rm -rf $TEMP
rsync -r --link-dest=$DEST --files-from=$FILELIST user@server:/ $TEMP/
rm -r $DEST
mv $TEMP $DEST

وهذا يرشد رسينك لاستخدام وجهة فارغة. الملفات الموجودة في الارتباط دست-الدليل بالفعل هي محليا ترتبط بجد وليس نسخها. وأخيرا يتم استبدال الوجهة القديمة واحدة جديدة. ومكدير الأول يخلق $ DEST فارغا إذا $ DEST لا وجود لها، لمنع الخطأ رسينك. (ويفترض أن -variables $ لتنفيذ المسار الكامل للملف المعني أو الدليل).

وهناك بعض النفقات العامة طفيف ل-ربط الصلب، ولكنك لا تحتاج إلى فوضى مع مجمع وتشمل / استبعاد استراتيجيات.

ومستوحاة من m4t، ولكن باستخدام ... رسينك لتنظيف

rsync -r --link-dest=$dst --files-from=filelist.txt user@server:$source/ $temp
rsync -ra --delete --link-dest=$temp $temp/ $dest

وصريحة بناء --exclude-من = ... يبدو أن الطريقة الوحيدة لقائمة الملفات مزامنة.

stdin = subprocess.PIPE
other_params.append("--exclude-from=-") #from stdin 

p = subprocess.Popen( 'rsync -e ssh -zthvcr --compress-level=9 --delete'.split() + other_params + [src, dst], stdin =  PIPE)

if relative_files_list != None:
    #hack: listing of excluded files seems the only way to delete unwanted files at destination
    files = set(map(norm_fn, relative_files_list)) #make hash table, for huge lists
    for path, ds, fs in os.walk(src):
        for f in fs:
            rel_path_f = norm_fn(os.path.relpath(os.path.join(path, f), src))
            if rel_path_f not in files:
                #print 'excluding', rel_path_f.replace('\\', '/')
                p.stdin.write(rel_path_f + '\n')
    p.stdin.close()
assert 0 == p.wait()

وأنا أدرك سئل هذا السؤال قبل فترة طويلة، لكنني كنت غير راض عن الإجابة.

وهنا هو كيف تحل المشكلة، على افتراض قائمة التشغيل التي أنشأتها mpd:

#!/bin/bash                                                                 

playlist_path="/home/cpbills/.config/mpd/playlists"
playlist="${playlist_path}/${1}.m3u"
music_src="/home/cpbills/files/music"
music_dst="/mnt/sdcard/music/"

if [[ -e "$playlist" ]]; then
  # Remove old files
  find "$music_dst" -type f | while read file; do
    name="$(echo "$file" | sed -e "s!^$music_dst!!")"
    if ! grep -qF "$name" "$playlist"; then
      rm "$file"
    fi
  done

  # Remove empty directories
  find "$music_dst" -type d -exec rmdir {} \; 2>/dev/null

  rsync -vu \
      --inplace \
      --files-from="$playlist" \
      "$music_src" "$music_dst"
else
  printf "%s does not exist\n" "$playlist" 1>&2
  exit 1
fi

رسينك مثالية لحفظ الدلائل في المزامنة ، من بين أشياء أخرى مفيدة.إذا كان لديك نسخة طبق الأصل عن المصدر ، و تريد حذف الملفات على دست يمكنك حذفها من المصدر rsync --delete خيار حذفها من دست أيضا.

ومع ذلك, إذا لديك فقط التعسفي قائمة الملفات التي تريد حذفها ، أقترح عليك استخدام SSH لتحقيق ذلك:

ssh user@remote.host.com rm /path/to/file1 /path/to/file2

هذا سيتم تنفيذ rm القيادة على المضيف البعيد.

باستخدام بيثون, يمكنك:

import subprocess
FileList = ['/path/to/file1', '/path/to/file2']
subprocess.call(['ssh', 'dAnjou@my.server.com', 'rm'] + FileList)

~الاستمتاع

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top