تغییر نام انبوه پرونده‌ها با افزودن شماره

اگر فهرست پخشی از یوتیوب بارگیری می‌کنید که فاقد شماره‌گذاری در نام پرونده است، حتما متوجه مشکل شده‌اید. اینجا تجربه‌ام برای تغییر نام انبوه در گنولینوکس را نوشته‌ام.

روز گذشته، ویدئوهای یک فهرست پخش را از یوتیوب بارگیری کردم. ۱۱۸ ویدئو در آن فهرست موجود بود که متاسفانه فاقد شماره سریال بودند. در نتیجه امکان تغییر نام و جابه‌جا کردن شماره سریال از انتها به ابتدای نام پرونده‌ها نبود. بنابراین نیاز بود راهی پیدا کنم باری اینکه پرونده‌ها مرتب و شماره سریالی به اول نام‌شان اضافه کنم. و پیش از ادامه، تاکید کنم که این کار، روی گنولینوکس #اوبونتو انجام شده است.

به لطف مرتب بودن ویدئو در فهرست پخش و اینکه برنامه youtube-dl آن‌ها را به همان ترتیب نمایش در فهرست، دریافت می‌کند، اطمینان داشتم که زمان ایجاد ویدئوها داخل پوشه، مرتب است. بنا بر این، با دستوری مثل ls -tr می‌شد پرونده‌ها را به ترتیب زمانی مشاهده کرد.

از اینجا به بعد کافی بود که بتوانم حلقه‌ای ایجاد کنم و بر اساس محتوای دستور ls نام پرونده‌ها را گفته و شماره‌ای به اول‌شان اضافه کنم. ابتدا به سراغ دستور for‍ رفتم. متاسفانه این دستور اگر به صورت for f in $(ls -tr) استفاده شود، متن را بر حسب فاصله هم از هم تفکیک مي‌کند. در نتیجه در عمل، امکان دریافت نام کامل (در صورتی که در نام پرونده، فاصله وجود داشته باشد) به این روش میسر نبود. لااقل من چیزی روی اینترنت پیدا نکردم.

روش دیگر این بود که ابتدا فهرست مرتب شده را با ls ایجاد کنم و سپس خروجی‌اش را به دستور دیگری مثل while read f بدهم. خوشبختانه این دستور به دلیل خواندن خط به خط، مشکل بالا را حل می‌کرد و به این ترتیب، نام هر پرونده را می‌توانستم در متغیر $f داشته باشم.

الان تنها کاری که لازم بود انجام شود، ایجاد یک متغیر برای شمارش و درج آن در اول نام پرونده و افزایش آن در هر بار پردازش داخل حلقه بود. برای اطمینان از این که تعداد رقم‌ها در شماره با هم برابر است و اولین ویدئو به صورت 001 نام‌گذاری می‌شود نه 1، از دستور قالب‌دهی به متن به این شکل استفاده کردم:

$(printf "%03d" $counter)

تغییر نام هم که با دستوری مثل rename به راحتی قابل انجام است. (البته من از rename روی اوبونتو استفاده می‌کنم که با rename روی برخی توزیع‌های گنولینوکسی دیگر مانند CentOS متفاوت است.) قبل از تغییر نام پرونده‌ها و تا رسیدن به نتیجه مطلوب، از گزینه n در این دستور استفاده می‌کنم که بدون تغییر نام، فقط بگوید که تغییر نام پرونده‌ها به چه شکل خواهد بود. نتیجه، چیزی شبیه به این می‌شود:

counter=1

ls -tr *.mp4 | while read name; do
    rename -n "s//$(printf \"%03d\" $counter) - /" "$name"
    counter=$((counter+1))
done

خروجی‌اش هم چیزی شبیه به این باید باشد:

rename(video first.mp4, "001" - video first.mp4)
rename(video second.mp4, "002" - video first.mp4)
...
rename(video last.mp4, "118" - video last.mp4)

و چون نتیجه، همان چیزی است که من می‌خواستم دستور را بدون گزینه n اجرا کردم. در نتیجه، به راحتی ۱۱۸ پرونده بدون شماره، دارای شماره شدند تا بتوان به راحتی ترتیب‌شان را دید. دستورات نهایی به این شرح‌اند:

counter=1

ls -tr *.mp4 | while read name; do
    rename "s//$(printf \"%03d\" $counter) - /" "$name"
    counter=$((counter+1))
done

این را نوشتم که بعدا برای خودم قابل ارجاع و استفاده مجدد باشد. موارد زیادی پیش می‌آید که نیاز به چنین کاری پیدا مي‌کنم. امیدوارم به درد دیگران هم بخورد. من، دانش محدودی در نوشتن کدهای شل دارم. لذا چیزی که نوشتم الزاما بهترین راه‌حل نیست. اگر راه بهتر و آسان‌تری برای این کار می‌شناسید، لطفا هم‌رسانی کنید.