كيف متكرر بفك المحفوظات في دليل الدلائل من سطر الأوامر يونكس?
سؤال
على unzip
الأمر لا خيار متكرر حيويي المحفوظات.
إذا كان لدي الدليل التالي هيكل و المحفوظات:
/Mother/Loving.zip /Scurvy/Sea Dogs.zip /Scurvy/Cures/Limes.zip
وأريد أن بفك جميع المحفوظات في الدلائل مع نفس الاسم مثل كل الأرشيف:
/Mother/Loving/1.txt /Mother/Loving.zip /Scurvy/Sea Dogs/2.txt /Scurvy/Sea Dogs.zip /Scurvy/Cures/Limes/3.txt /Scurvy/Cures/Limes.zip
ما الأمر أو الأوامر أود أن المسألة ؟
المهم أن هذا لا تختنق أسماء الملفات التي تحتوي على مسافات في نفوسهم.
المحلول
إذا كنت تريد استخراج الملفات إلى مجلد منها يمكنك أن تجرب هذا
find . -name "*.zip" | while read filename; do unzip -o -d "`dirname "$filename"`" "$filename"; done;
متعدد الإصدار المصنعة للأنظمة التي يمكن التعامل مع ارتفاع I/O:
find . -name "*.zip" | xargs -P 5 -I fileName sh -c 'unzip -o -d "$(dirname "fileName")/$(basename -s .zip "fileName")" "fileName"'
نصائح أخرى
هنا حل واحد ينطوي على العثور على الأوامر و حلقة while:
find . -name "*.zip" | while read filename; do unzip -o -d "`basename -s .zip "$filename"`" "$filename"; done;
حل بشكل صحيح يعالج جميع أسماء الملفات (بما في ذلك أسطر) ومقتطفات إلى الدليل الذي هو في نفس الموقع مثل الملف مع التمديد إزالة:
find . -name '*.zip' -exec sh -c 'unzip -o -d "${0%.*}" "$0"' '{}' ';'
لاحظ أنه يمكنك بسهولة جعل ذلك التعامل مع المزيد من أنواع الملفات (مثل .jar
) قبل إضافتها باستخدام -o
, مثل:
find . '(' -name '*.zip' -o -name '*.jar' ')' -exec ...
هل يمكن استخدام تجد جنبا إلى جنب مع -exec العلم في سطر أوامر واحد للقيام بهذه المهمة
find . -name "*.zip" -exec unzip {} \;
شيء مثل gunzip باستخدام-r العلم؟....
السفر بنية الدليل بشكل متكرر.إذا كان أي من أسماء الملفات المحددة في سطر الأوامر هي الدلائل, gzip سوف ينزل إلى الدليل و ضغط جميع الملفات التي يجدها هناك (أو ضغط عليها في حالة gunzip ).
هذا يعمل تماما كما نريد:
فك ضغط الملفات:
find . -name "*.zip" | xargs -P 5 -I FILENAME sh -c 'unzip -o -d "$(dirname "FILENAME")" "FILENAME"'
الأمر أعلاه لا يخلق مكررة الدلائل.
إزالة كل الملفات المضغوطة:
find . -depth -name '*.zip' -exec rm {} \;
إذا كنت تستخدم cygwin, بناء الجملة هو مختلفة قليلا عن basename الأمر.
find . -name "*.zip" | while read filename; do unzip -o -d "`basename "$filename" .zip`" "$filename"; done;
أنا أدرك أن هذه هي قديمة جدا ، ولكن كان من بين أول من يضرب على جوجل عندما كنت أبحث عن حل شيئا من هذا القبيل ، حتى أنا بعد ما فعلت هنا.السيناريو بلدي هو مختلفة قليلا كما في الأساس أردت أن تنفجر بالكامل جرة ، جنبا إلى جنب مع جميع الجرار الواردة في ذلك ، لذا كتبت التالية باش وظائف:
function explode {
local target="$1"
echo "Exploding $target."
if [ -f "$target" ] ; then
explodeFile "$target"
elif [ -d "$target" ] ; then
while [ "$(find "$target" -type f -regextype posix-egrep -iregex ".*\.(zip|jar|ear|war|sar)")" != "" ] ; do
find "$target" -type f -regextype posix-egrep -iregex ".*\.(zip|jar|ear|war|sar)" -exec bash -c 'source "<file-where-this-function-is-stored>" ; explode "{}"' \;
done
else
echo "Could not find $target."
fi
}
function explodeFile {
local target="$1"
echo "Exploding file $target."
mv "$target" "$target.tmp"
unzip -q "$target.tmp" -d "$target"
rm "$target.tmp"
}
ملاحظة <file-where-this-function-is-stored>
الذي هو ضروري إذا كنت تخزين هذا الملف الذي لا يقرأ غير التفاعلية قذيفة كما حدث لي أن يكون.إذا كنت تخزين المهام في ملف محملة على غير التفاعلية قذائف (على سبيل المثال ، .bashrc
وأعتقد) يمكنك إسقاط كل source
البيان.نأمل أن هذا سوف يساعد شخص ما.
تحذير بسيط - explodeFile
أيضا حذف ziped الملف يمكنك بالطبع تغيير هذا عن طريق التعليق الخروج السطر الأخير.
حل آخر للاهتمام ليكون:
DESTINY=[Give the output that you intend]
# Don't forget to change from .ZIP to .zip.
# In my case the files were in .ZIP.
# The echo were for debug purpose.
find . -name "*.ZIP" | while read filename; do
ADDRESS=$filename
#echo "Address: $ADDRESS"
BASENAME=`basename $filename .ZIP`
#echo "Basename: $BASENAME"
unzip -d "$DESTINY$BASENAME" "$ADDRESS";
done;