چرا گنو/لینوکس رو دوست دارم: انتقال کلی کتاب به پوشه هم نامشون

یک دوست ایمیل زده که:

۱۲۰۰ تا کتاب دارم که همه در یک دایرکتوری هستن. می خوام یک دایرکتوری برای هر یک کتاب ساخته بشه و کتاب بره توی دایرکتوری خودش. یعنی می خوام ۱۲۰۰ تا دایرکتوری بسازم و هر کتاب رو کپی کنم سر جاش.

چراش رو من نمی دونم… ولی چجوری اش رو می دونم: گنو/لینوکس پر از ابزارهای ریز است که هر کدوم برای کار خودشون بهترین هستن و ترکیب اینها باعث می شه بشه تقریبا هر چیزی ساخت. کل کار رو می شه توی یک خط انجام داد اما پیچیدگی با احتمال استفاده شدن فاصله در نام فایل بیشتر می شه. حتما روش های ساده تر هم هست اما من اینطوری نوشتم:

jadi@freebasse:/tmp/books$ cat ../p.sh
#!/bin/bash

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for f in books/*
do
  mkdir "$f"_dir
  mv "$f" "$f"_dir/
  echo "$f"
done
IFS=$SAVEIFS

یک حلقه for است که همه فایل ها رو یکی یکی می ندازه وسط دایره. هر کی وسط باشه اول یک فولدر براش ساخته می شه با _dir و بعد یک mv روش اجرا می شه و خلاص. اون IFS متغیری است که توی بش تعریف می کنه جدا کننده فیلدها از هم باید چی باشه. معمولا اسپیس است اما چون اینجا ممکنه اسم فایل توش اسپیس داشته باشه، کردیمش «سرخط».

نکته: دوستم بعد از گرفتن این گفت که کامپیوتر ویندوزی است (: کماکان راحته. کافیه یک اوبونتو یا هر توزیع لینوکس دیگه دانلود کنید، روی یو اس بی نصبش کنین و لایو بوت کنین و این کارها رو انجام بدین و دوباره بوت کنین و برگردین توی ویندوز عزیز. مثل همیشه: بک آپ فراموش نشه!

آپدیت: دوست خوبم مهدی بیگی توی کامنت ها این شیوه راحت تر و بهتر رو پیشنهاد داده:


find -type f -exec mkdir '{}'.tmp \; -exec mv '{}' '{}'.tmp \; -exec mv '{}'.tmp '{}' \;

که فقط یک دستور است. دستور find می تونه چیزهای مختلف رو پیدا کنه و اینجا با سوییچ f دنبال فایل می گرده. بعد روی تک تک اون فایل ها چیزی که جلوی سوییچ exec هست رو اجرا می کنه و هر بار به جای {} یکی از فایل های پیدا شده رو می ذاره. در نهایت هم اسلش سمی کالن می گه چیزی که جلوی سوییچ exec بوده تموم شده.