انجمن‌های فارسی اوبونتو

تازه کار => انجمن تازه‌کاران => نویسنده: mostafa7091 در 31 امرداد 1400، 12:27 ق‌ظ

عنوان: راهنمایی برای نوشتن یک دستور در ترمینال (حل شد)
ارسال شده توسط: mostafa7091 در 31 امرداد 1400، 12:27 ق‌ظ
سلام دوستان
من با اوبونتو 20.04 کار میکنم.
چند وقتی هست که دنبال دستوری میگردم تا بشه با اون محتویات یک دایرکتوری خونده بشه و بعد به طور مثال فایل nام انتخاب بشه تا عمل مورد نظرم رو روش انجام بدم. توضیحات ls رو نگاه کردم ولی نتونستم چیزی پیدا کنم.
ممنون میشم کمکم کنید  :)
عنوان: پاسخ : راهنمایی برای نوشتن یک دستور در ترمینال
ارسال شده توسط: sameet در 31 امرداد 1400، 09:08 ق‌ظ
سوالت رو دقیق متوجه نشدم ولی برنامه ای هست یه اسم ( Tree ) که شاید کمکت کنه .
عنوان: پاسخ : راهنمایی برای نوشتن یک دستور در ترمینال
ارسال شده توسط: جعفر فرقانلوژ در 31 امرداد 1400، 10:57 ق‌ظ
سلام دوستان
من با اوبونتو 20.04 کار میکنم.
چند وقتی هست که دنبال دستوری میگردم تا بشه با اون محتویات یک دایرکتوری خونده بشه و بعد به طور مثال فایل nام انتخاب بشه تا عمل مورد نظرم رو روش انجام بدم. توضیحات ls رو نگاه کردم ولی نتونستم چیزی پیدا کنم.
ممنون میشم کمکم کنید  :)

با ls می تونید محتوای یک شاخه رو ببینید
ولی منظورتون رو نفهمیدم می خواین یک عمل رو به ترتیب روی تک تک فایل های یک شاخه انجام بدید ؟
عنوان: پاسخ : راهنمایی برای نوشتن یک دستور در ترمینال
ارسال شده توسط: mostafa7091 در 31 امرداد 1400، 11:06 ق‌ظ
سوالت رو دقیق متوجه نشدم ولی برنامه ای هست یه اسم ( Tree ) که شاید کمکت کنه .
سلام sameet جان
ممنون از پاسخت. توضیحات tree رو دیدم ولی چیزی به ذهنم نرسید برای حل مشکلم. البته که مبتدی و تازه کار هستم.
اجازه بده یکم بیشتر توضیح بدم:
من روی تصاویر MRI کار میکنم با همچین ساختاری:
(base) mostafa@mostafa-Inspiron-N5110:~/Desktop/server/result/90$ ls
90_clean_P_all_L_Angular_Gyrus.nii.gz                             90_clean_P_all_L_Paracingulate_Cortex.nii.gz
90_clean_P_all_L_Anterior_Cingulate_Gyrus.nii.gz                  90_clean_P_all_L_Parahippocampus.nii.gz
90_clean_P_all_L_Central_Operculum.nii.gz                         90_clean_P_all_L_Parietal_Operculum.nii.gz
90_clean_P_all_L_Cuneal_Cortex.nii.gz                             90_clean_P_all_L_Planum_Polare.nii.gz
90_clean_P_all_L_Frontal_Medial_Cortex.nii.gz                     90_clean_P_all_L_Planum_Temporale.nii.gz
90_clean_P_all_L_Frontal_Operculum.nii.gz                         90_clean_P_all_L_Postcentral_Gyrus.nii.gz
90_clean_P_all_L_Frontal_Orbital_Cortex.nii.gz                    90_clean_P_all_L_Posterior_Cingulate_Gyrus.nii.gz
90_clean_P_all_L_Frontal_Pole.nii.gz                              90_clean_P_all_L_Precentral_Gyrus.nii.gz
90_clean_P_all_L_Heschls_Gyrus.nii.gz                             90_clean_P_all_L_Precuneus_Cortex.nii.gz
90_clean_P_all_L_Inferior_Frontal_Gyrus_pars_opercularis.nii.gz   90_clean_P_all_L_Subcallosal_Cortex.nii.gz
90_clean_P_all_L_Inferior_Frontal_Gyrus_pars_triangularis.nii.gz  90_clean_P_all_L_Superior_Frontal_Gyrus.nii.gz
90_clean_P_all_L_Inferior_Lateral_Occipital_Cortex.nii.gz         90_clean_P_all_L_Superior_Lateral_Occipital_Cortex.nii.gz
90_clean_P_all_L_Inferior_Temporal_Gyrus.nii.gz                   90_clean_P_all_L_Superior_Parietal_Lobule.nii.gz
90_clean_P_all_L_Insular_Cortex.nii.gz                            90_clean_P_all_L_Superior_Temporal_Gyrus.nii.gz
90_clean_P_all_L_Intracalcarine_Cortex.nii.gz                     90_clean_P_all_L_Supracalcarine_Cortex.nii.gz
90_clean_P_all_L_Juxtapositional_Lobule.nii.gz                    90_clean_P_all_L_Supramarginal_Gyrus.nii.gz
90_clean_P_all_L_Lingual_Gyrus.nii.gz                             90_clean_P_all_L_Temporal_Fusiform_Cortex.nii.gz
90_clean_P_all_L_Middle_Frontal_Gyrus.nii.gz                      90_clean_P_all_L_Temporal_Occipital_Fusiform_Cortex.nii.gz
90_clean_P_all_L_Middle_Temporal_Gyrus.nii.gz                     90_clean_P_all_L_Temporal_Pole.nii.gz
90_clean_P_all_L_Occipital_Fusiform_Cortex.nii.gz                 90_clean_P_all_L_Temporoccipital_Inferior_Temporal_Gyrus.nii.gz
90_clean_P_all_L_Occipital_Pole.nii.gz                            90_clean_P_all_L_Temporoccipital_Middle_Temporal_Gyrus.nii.gz

بطور مثال اسکریپتی مینویسم و در قسمت اول میخوام تصویر اول با چهارم و تصویر nام با mام رو با هم جمع کنم تا برای بقیه پردازشها اماده بشن. با توجه به اینکه این اسکریپت رو برای پوشه های دیگری هم میخوام استفاده کنم ولی تصاویر انتخابی متفاوتن, نمیشه از اسم تصاویر درون اسکریپت استفاده کنم. چون اسمها طولانی هستن و زمان بر هست اینکار. برای حل این مشکل یکار که میتونم انجام بدم این هست که تصاویر رو رینیم کنم و نامهاشون رو به 1 تا n تغییر بدم و داخل اسکریپت به وسیله اعداد تصاویر رو فراخوان کنم که بسیار ساده میشه در مرحله اول اما وقتی میخوام تصاویر رو دوباره رینیم کنم و اسامی اصلیشون رو جایگزین کنم به مشکل زیادی میخورم. بخاطر همین خواستم ببینم ایا دستوری هست که محتویات یک پوشه رو بخونیم و بعد بگیم براساس sort ای که انجام داده فایل دوم و چهارم رو بما بده؟
اینطوری اسکریپت وابسته به نام فایلها نیست و وقتی نام ها تغییر میکنه مشکلی نداریم و همچنین نیازی به 2بار رینیم کردن هم نیست.
تونستم منظور رو برسونم؟
عنوان: پاسخ : راهنمایی برای نوشتن یک دستور در ترمینال
ارسال شده توسط: mostafa7091 در 31 امرداد 1400، 11:11 ق‌ظ
سلام دوستان
من با اوبونتو 20.04 کار میکنم.
چند وقتی هست که دنبال دستوری میگردم تا بشه با اون محتویات یک دایرکتوری خونده بشه و بعد به طور مثال فایل nام انتخاب بشه تا عمل مورد نظرم رو روش انجام بدم. توضیحات ls رو نگاه کردم ولی نتونستم چیزی پیدا کنم.
ممنون میشم کمکم کنید  :)

با ls می تونید محتوای یک شاخه رو ببینید
ولی منظورتون رو نفهمیدم می خواین یک عمل رو به ترتیب روی تک تک فایل های یک شاخه انجام بدید ؟
سلام Mehr32 جان
نکته همینجا هست که روی تک تک فایلهای نمیخوام کاری کنم بلکه روی چنتاشون هست و در دفعات بعدی هم عوض میشن و تکراری نیست روند و دارم سعی میکنم اسکریپتی بنویسم که هربار نیاز به کمترین ویرایش داشته باشه.یعنی هربار در حد عوض کردن چند عدد.
عنوان: پاسخ : راهنمایی برای نوشتن یک دستور در ترمینال
ارسال شده توسط: Issac در 31 امرداد 1400، 12:12 ب‌ظ
سلام.
میخواین برای ورودی به اسکریپت‌تون مثلا یکی یا دوتا عدد بدید و اسکریپت بر اساس ترتیبی که خودتون تو اسکریپت گفتید، یه عمل روی فایل متناظر با اون عدد انجام بده؟ مثلا شما عدد 3 رو بفرستید و اون اسکریپت پروندهٔ سوم رو استخراج کنه؟(یا هر کار دیگه)
میخواین به اسکریپت‌تون چند تا ورودی بدید؟(یکی، دوتا، هفت‌تا، نامعلوم)
به چه صورت میخواین مرتبشون کنید؟(تاریخ، اندازه، اسم)
اگه اسکریپت‌تون رو بتونین قرار بدین راحت‌تر میشه کمک کرد.
عنوان: پاسخ : راهنمایی برای نوشتن یک دستور در ترمینال
ارسال شده توسط: Dragon- در 31 امرداد 1400، 12:57 ب‌ظ
این رو بررسی کنید
ls | awk 'BEGIN{ RS = "" ; FS = "\n" }{print $2" "$3}'
این اول محتوای یه دایرکتوری رو لیست می‌کنه بعد خروجی رو می‌فرسته به awk بعد اونجا دومین و سومین عضو نمایش داده میشه.
خروجی ls بر اساس حروف مرتب شده.
یه‌راه برای اینکه لازم نباشه هر بار اسکریپت رو تغییر ندید این هست که موقع اجرا، مقادیر رو جلوی اسکریپت بنویسید. و بعد awk رو هم تنظیم کنید که بعضی متغیر‌های خودش رو از bash بگیره.
مثلا این رو ببینید
#!/bin/bash
if [[ "$1" =~ ^[0-9]+$ ]]; then
      number=$1
else
      echo "Invalid input."
      echo "Expexted to recive integer."
      exit 1
fi
elements_count=$(ls | wc -l)
echo "This directory has $elements_count"
if [ $number -gt $elements_count ]; then
      echo "Input exceeds the directory elements count"
      echo "Enter an integer lower than $element_count"
      exit 1
fi
if [ $number -eq 0 ]; then
      echo "0 is not acceptable"
      exit 1
fi

ls | awk -v number=$number 'BEGIN{ RS = "" ; FS = "\n" }{print $number" "$(number+1)}'

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

مثلا اگه فایل رو با اسم test.sh ذخیره کنید. موقع اجرا، اگه اینجوری اجراش کنید، اسم فایل پنجم و ششم نمایش داده میشه
./test.sh 5
میشه این رو تغییر داد تا دوتا عدد بگیره و اسم دوتا فایل رو نمایش بده که الزاما پشت‌سر‌هم نیستن. البته بعیده نمایش اسم کاری برای شما انجام بده. می‌تونید اون اسم‌ها رو توی متغیر‌های دیگه ذخیره کنید و بعد در ادامه از اونها استفاده کنید یا اینکه خروجی awk رو بدید به یه چیز دیگه تا اون کار‌های لازم رو انجام بده.
عنوان: پاسخ : راهنمایی برای نوشتن یک دستور در ترمینال
ارسال شده توسط: mostafa7091 در 31 امرداد 1400، 03:40 ب‌ظ
این رو بررسی کنید
ls | awk 'BEGIN{ RS = "" ; FS = "\n" }{print $2" "$3}'
این اول یه محتوای یه دایرکتوری رو لیست می‌کنه بعد خروجی رو می‌فرسته به awk بعد اونجا دومین و سومین عضو نمایش داده میشه.
خروجی ls بر اساس حروف مرتب شده.
یه‌راه برای اینکه لازم نباشه هر بار اسکریپت رو تغییر ندید این هست که موقع اجرا، مقادیر رو جلوی اسکریپت بنویسید. و بعد awk رو هم تنظیم کنید که بعضی متغیر‌های خودش رو از bash بگیره.
مثلا این رو ببینید
#!/bin/bash
if [[ "$1" =~ ^[0-9]+$ ]]; then
      number=$1
else
      echo "Invalid input."
      echo "Expexted to recive integer."
      exit 1
fi
elements_count=$(ls | wc -l)
echo "This directory has $elements_count"
if [ $number -gt $elements_count ]; then
      echo "Input exceeds the directory elements count"
      echo "Enter an integer lower than $element_count"
      exit 1
fi
if [ $number -eq 0 ]; then
      echo "0 is not acceptable"
      exit 1
fi

ls | awk -v number=$number 'BEGIN{ RS = "" ; FS = "\n" }{print $number" "$(number+1)}'

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

مثلا اگه فایل رو با اسم test.sh ذخیره کنید. موقع اجرا، اگه اینجوری اجراش کنید، اسم فایل پنجم و ششم نمایش داده میشه
./test.sh 5
میشه این رو تغییر داد تا دوتا عدد بگیره و اسم دوتا فایل رو نمایش بده که حتما پشت‌سر‌هم نباشن. البته بعیده نمایش اسم کاری برای شما انجام بده. می‌تونید اون اسم‌ها رو توی متغیر‌های دیگه ذخیره کنید و بعد در ادامه از اونها استفاده کنید یا اینکه خروجی awk رو بدید به یه چیز دیگه تا اون کار‌های لازم رو انجام بده.

سلام Dragon جان
کدی که نوشتی عالی هست و دقیقن چیزی هست که میخوام حتی فراتر از خواسته م هست. نمیدونم چطور تشکر کنم.
خیلی ممنونم  :)
از همه دوستانی هم که وقت گذاشتن و سعی کردن مشکلم رو حل کن تشکر میکنم :)