پردازش متن (Text Processing)
تمامی سیستمهای یونیکسی بهشدت متکی به فایلهای متنی از انواع مختلف دادههای ذخیرهسازی هستند. بنابراین وجود ابزارهای متعدد برای دستکاری متن در یونیکس، منطقی به نظر میرسد.
در این درس و درسهای بعدی برنامههای زیادی را بهمنظور پردازش متن بررسی خواهیم کرد.
این فرمانها عبارت خواهند بود ازcat ، sort، uniq، cut، paste، join، comm، diff، patch، tr، sed و aspell.
اپلیکیشنهای متن
تا بدینجا درباره برخی از ویرایشگرهای متن، مانند nano و vim آموختیم و بهوسیله آنها برخی فایلهای پیکربندی را دستکاری کردیم و برخی از فرمانها را اجرا نمودیم؛ اما اینجا پایان کار نیست. موارد زیاد دیگری هستند که با متن ارتباط دارند.
اسناد (Documents)
بسیاری از افراد، اسناد خود را در فرمتهای متن ساده مینویسند. در حالیکه یک فایل متنی کوچک برای نگهداری متنها مفید است، میتوان از متن برای نوشتن اسناد بزرگتر نیز استفاده کرد. رویکردی رایج، نوشتن اسناد بزرگ در فرمت متن (text) است.
سپس میتوان با استفاده از یک زبان نشانهگذاری فرمت سند پایانی را توصیف کرد. بسیاری از مقالات علمی به این شیوه نوشته شدهاند.
صفحات وب (Web Pages)
رایجترین نوع اسناد الکترونیک، صفحات وب هستند. صفحات وب اسناد متنی هستند که بهوسیله استانداردهای HTML و یا XML نوشته شدهاند که زبانهای نشانهگذاری برای توصیف فرمت صفحات وب هستند. همچنین از اسنادی با فرمت CSS میتوان بهمنظور تغییر ظاهر این صفحات و نمایش تصویری آنها استفاده کرد که این اسناد نیز متنی هستند.
ایمیل
ایمیل، اساسا رسانهای است که بر مبنای متن ایجاد شده است. حتی پیوستهایی که فرمت متنی ندارند و به ایمیل ضمیمه میشوند نیز بهمنظور انتقال، به متن تبدیل میشوند و در مقصد دوباره شکل اولیه خود را بهدست میآورند. اینکار را میتوان با دانلود یک پیام ایمیل و سپس نمایش آن توسط فرمان less مشاهده کرد. در این حالت خواهیم دید که پیام ایمیل با یک Header آغاز شده که منبع پیام و پردازش آن، در طی ارسال را توصیف میکند و سپس بدنه پیام و محتویات پیام مشاهده خواهد شد.
خروجی پرینتر
در سیستمهای یونیکسمحور، خروجی که به یک پرینتر ارسال میگرد، بهصورت متن ساده ارسال میگردد و یا اگر صفحه دارای محتوای گرافیکی باشد، محتوای گرافیکی تبدیل به متن (با فرمت متنی تحت عنوان PostScript) شده و سپس به برنامهای که نقاط گرافیکی را برای چاپ ایجاد میکند، ارسال میشود.
کد منبع (Source Code) برنامهها
بسیاری از برنامههای خط فرمان که در سیستمهای یونیکس وجود دارند، از این جهت ایجاد شدهاند تا مدیریت سیستم و توسعه نرمافزار را پشتیبانی کنند و برنامههای پردازش متن نیز مستثنی نیستند.
بسیاری از آنها طراحی شدهاند تا مشکلات توسعه نرمافزاری را حل نمایند. علت آنکه پردازش متن برای توسعهدهندگان نرمافزار بسیار اهمیت دارد، این است که همه نرمافزارها بهصورت متن شروع میشوند؛ یعنی همه نرمافزارها دارای یک کد منبع (Source Code) متنی هستند که برنامهنویس آن را نوشته است و سپس این متن توسط کامپایلر تفسیر شده و نرمافزار را ایجاد میکند. پس همیشه به یاد داشته باشید که همه چیز از متن ساده آغاز شده است.
فرمان cat (الحاق فایلها و چاپ آنها در خروجی استاندارد)
فرمان cat گزینههای جذاب زیادی دارد. بسیاری از آنها بهمنظور تجسم بهتر محتوای متن استفاده میشوند. نمونهای از آنها گزینه –A میباشد که به منظور نمایش کاراکترهای چاپ شدنی درون متن استفاده میشوند. در برخی مواقع ما میخواهیم بدانیم که آیا کاراکترهای کنترل شده درون متن ما وجود دراند یا نه.
رایجترین آنها کاراکترهای tab (بر خلاف فاصلهها) و کاراکتر Return هستند. موقعیت رایجی دیگر، فایلی است که حاوی خطوط متن با فاصلههای دنبالهدار میباشد.
حال، یک فایل آزمایشی را با استفده از cat (بهعنوان یم پردازشگر ابتدایی متن) ایجاد میکنیم. بدین منظور، فرمان cat را (در ادامه فایلی که خروجی را به درون آن میریزیم) وارد میکنیم و سپس متن دلخواه خود را وارد کرده و در آخر متن، کلید Enter را فشرده تا خط بهصورت صحیح پایان یابد. سپس برای اینکه به cat بفهمانیم که فایل به پایان رسیده Ctrl+D را فشار میدهیم. در این مثال، ما یک کاراکتر tab در ابتدای متن بههمراه تعدادی فاصله وارد کردیم.
1 2 3 |
[me@linuxbox ~]$ cat > foo.txt The quick brown fox jumped over the lazy dog. [me@linuxbox ~]$ |
سپس با استفاده از فرمان cat به همراه گزینه –A بهمنظور نمایش متن استفاده میکنیم:
1 2 3 |
[me@linuxbox ~]$ cat -A foo.txt ^IThe quick brown fox jumped over the lazy dog. $ [me@linuxbox ~]$ |
همانطور که میبینیم، کاراکتر tab در متن مربوطه با استفاده از علامت ^I ارایه میشود. علاوه بر آن، میبینیم که علامت $ در پایان متن نمایان میشود، که دلیل آن، فشردن Enter است و بیانگر این است که خط به پایان رسیده و فاصاه انتهایی وجود دارد.
علاوه بر این، فرمان cat، دارای گزینههایی برای تغییر متن نیز میباشد. دو مورد از برجستهترین آنها –n و –s هستند. گزینه –n خطوط را شمارهگذاری میکند و گزینه –s مانع از خروج چندین خط خالی میشود. میتوانیم به شیوه زیر آن را نمایش دهیم:
1 2 3 4 5 6 7 8 |
[me@linuxbox ~]$ cat > foo.txt The quick brown fox jumped over the lazy dog. [me@linuxbox ~]$ cat -ns foo.txt 1 The quick brown fox 2 3 jumped over the lazy dog. [me@linuxbox ~]$ |
در این مثال، همانگونه که مشاهده میکنید، نسخه جدیدی از فایل foo.txt ایجاد کردیم که در بین خطوط آن، بیش از یک فاصله وجود دارد. سپس با استفاده از گزینههای –n و –s خطوط را شمارهگذاری و فاصلههای اضافی آنها را برای نمایش، حذف نمودیم.
فرمان sort (بهمنظور مرتبسازی خطوط فایلهای متنی)
فرمان sort محتوای ورودی استاندارد یا یکی از فایلهایی که در خط فرمان اختصاص یافته را مرتب میکند و نتایج را به استاندارد خروجی ارسال مینماید. با استفاده از همان تکنیکی که در فرمان cat استفاده کردیم، میتوانیم پردازش ورودی استاندارد را بهصورت مستقیم از صفحهکلید نشان دهیم:
1 2 3 4 5 6 7 8 |
[me@linuxbox ~]$ sort > foo.txt c b a [me@linuxbox ~]$ cat foo.txt a b c |
مثال، گویای مطلب است. ابتدا فایل جدید foo.txt را با محتوای بههم ریخته خروف ایجاد کردیم. سپس با استفاده از فرمان cat نمایش عادی آن را نشان دادیم و در نهایت با استفاده از فرمان sort آن را بهصورت مرتب شده نشان دادیم.
از آنجایی که فرمان sort قادر به پذیرفتن چندین فایل بهعنوان آرگومان است، میتوان چندین فایل را با هم بهعنوان یک فایل مرتب شه، یکپارچه کرد.
برای مثال اگر سه فایل متنی بهصورت زیر داشته باشیم، میتوانیم آن را به اینگونه ادغام کنیم:
1 |
sort file1.txt file2.txt file3.txt > final_sorted_list.txt |
فرمان sort دارای گزینههای جذابی است که در جدول زیر مشاهده میکنید:
گزینه | گزینه طولانی | توضیحات |
---|---|---|
-b | --ignore-leading-blanks | بصورت پیشفرض مرتبسازی بر روی کل خط انجام میشود. که با اولین کاراکتر موجود در خط آغاز میگردد. این گزینه موجب میشود تا sort فضاهای پیشین در خط را نادیده بگیرد و مرتبسازی بر اساس اولین کاراکتر غیرفضای خالی موجود در خط انجام دهد. |
-f | --ignore-case | مرتبسازی را نسبت به حروف بزرگ و کوچک غیرحساس میکند. |
-n | --numeric-sort | مرتبسازی را براساس ارزیابی عددی یک رشته انجام میدهد. با استفاده از این گزینه شما میتوانید مرتبسازی را به جای مقادیر الفبایی براساس مقادیر عددی انجام دهید. |
-r | --reverse | مرتبسازی براساس ترتیب معکوس. نتایج به جای صعودی، نزولی انجام میشود. |
-k | --key=field1[,field2] | مرتبسازی براساس یک فیلد کلیدی از field1 تا field2 به جای کل خط. |
-m | --merge | هر کدام از آرگومانها را یه عنوان نام یک فایلاز قبل مرتب شده در نظر میگیرد. ادغام چندین فایل چندین فایل به درون نتایج یک فایل مرتب شده بدون انجام هر نوع مرتبسازی اضافی. |
-o | --output=file | ارسال خروجی مرتب شده به فایل به جای ارسال به خروجی استاندارد. |
-t | --field-separator=char | تعریف کاراکتر جداکننده فیلد، بصورت پیشفرض، فیلدها با فضای خالی با تب جدا شدهاند. |
اگرچه بیشتر گزینههایی که در بالا وجود دارد، واضح و روشنند، اما برخی از آنها اینگونه نیستند. ابتدا نگاهی به گزینه –n میاندازیم که بهمنظور مرتبسازی استفاده شده است. با استفاده از این گزینه، میتوانیم مقادیر را برمبنای مقدار عددی مرتب کنیم. این موضوع را میتوان بهوسیله نتایج بهدست آمده از فرمان du برای تشخیص بزرگترین مصرفکنندگان فضای دیسک در سیستم نشان دهیم. بهطور عادی، فرمان du نتایج خلاصهای را بر اساس ترتیب نام مسیر، لیست میکند:
1 2 3 4 5 6 7 8 9 10 11 |
[me@linuxbox ~]$ du -s /usr/share/* | head 252 /usr/share/aclocal 96 /usr/share/acpi-support 8 /usr/share/adduser 196 /usr/share/alacarte 344 /usr/share/alsa 8 /usr/share/alsa-base 12488 /usr/share/anthy 8 /usr/share/apmd 21440 /usr/share/app-install 48 /usr/share/application-registry |
در این مثال، نتایج را درون head پایپ کردیم تا نتایج بهدست آمده را به اندازه ده خط محدود کنیم. میتوانیم یک لیست عددی مرتب شده ایجاد کنیم تا 10 مصرفکننده بزرگ فضای دیسک در سیستم را نشان دهیم:
1 2 3 4 5 6 7 8 9 10 11 |
[me@linuxbox ~]$ du -s /usr/share/* | sort -nr | head 509940 /usr/share/locale-langpack 242660 /usr/share/doc 197560 /usr/share/fonts 179144 /usr/share/gnome 146764 /usr/share/myspell 144304 /usr/share/gimp 135880 /usr/share/dict 76508 /usr/share/icons 68072 /usr/share/apps 62844 /usr/share/foomatic |
با استفاده از گزینههای –nr یک ترتیب عددی برعکس ایجاد میکنیم. بدین صورت که بزرگترین مقادیر در ابتدا نمایش داده میشوند. ولی اگر بخواهیم لیستی را بر اساس برخی مقادی پیدا شده درون خطوط مرتب کنیم، چه باید کرد؟
بهعنوان مثال، نتیج بهدست آمده از فرمان ls –l بهصورت زیر است:
1 2 3 4 5 6 7 8 9 10 11 |
[me@linuxbox ~]$ ls -l /usr/bin | head total 152948 -rwxr-xr-x 1 root root 34824 2012-04-04 02:42 [ -rwxr-xr-x 1 root root 101556 2011-11-27 06:08 a2p -rwxr-xr-x 1 root root 13036 2012-02-27 08:22 aconnect -rwxr-xr-x 1 root root 10552 2011-08-15 10:34 acpi -rwxr-xr-x 1 root root 3800 2012-04-14 03:51 acpi_fakekey -rwxr-xr-x 1 root root 7536 2012-04-19 00:19 acpi_listen -rwxr-xr-x 1 root root 3576 2012-04-29 07:57 addpart -rwxr-xr-x 1 root root 20808 2012-01-03 18:02 addr2line -rwxr-xr-x 1 root root 489704 2012-10-09 17:02 adept_batch |
میتوانیم با استفاده از sort این لیست را براساس اندازه فایل نیز مرتب کنیم (هر چند این کار با خود فرمان ls هم قابل انجام است):
1 2 3 4 5 6 7 8 9 10 11 |
[me@linuxbox ~]$ ls -l /usr/bin | sort -nr -k 5 | head -rwxr-xr-x 1 root root 8234216 2012-04-07 17:42 inkscape -rwxr-xr-x 1 root root 8222692 2012-04-07 17:42 inkview -rwxr-xr-x 1 root root 3746508 2012-03-07 23:45 gimp-2.4 -rwxr-xr-x 1 root root 3654020 2012-08-26 16:16 quanta -rwxr-xr-x 1 root root 2928760 2012-09-10 14:31 gdbtui -rwxr-xr-x 1 root root 2928756 2012-09-10 14:31 gdb -rwxr-xr-x 1 root root 2602236 2012-10-10 12:56 net -rwxr-xr-x 1 root root 2304684 2012-10-10 12:56 rpcclient -rwxr-xr-x 1 root root 2241832 2012-04-04 05:56 aptitude -rwxr-xr-x 1 root root 2202476 2012-10-10 12:56 smbcacls |
بسیاری از استفادههای فرمان sort مستلزم پردازش دادههای جدولی، مثل نتایج بهدست آمده از فرمان ls در بالا است. اگر از واژگان پایگاهداده برای جدول بالا استفاده کنیم، میتوانیم بگوییم که هر سطر یک رکورد است و هر رکورد شامل چندین فیلد (مانند مشخصههای فایل، تعداد لینکها، اندازه فایل و …). اکنون فرمان sort قادر خواهد بود تا هر کدام از این فیلدها را پردازش کند.
در اصطلاح پایگاهداده، ما قادر هستیم که یک یا چند فیلد کلیدی را بهمنظور استفاده برای کلیدهای مرتبسازی تعیین کنیم. در مثال بالا، گزینههای –n و –r را بهمنظور مرتبسازی عددی برعکس اختصاص دادیم و با استفاده از –k 5 باعث شدیم که sort از پنج فیلد بهعنوان کلیدی برای مرتبسازی استفاده کند.
گزینه –k بسیار جالب است و ویژگیهای زیادی دارد، ولی ابتدا نیاز داریم ببینیم که sort چگونه فیلدها را تعریف میکند. فرض کنید یک فایل متنی ساده را که از یک خط که دارای نام نویسنده است، تشکیل شده است:
1 |
William Shotts |
بهطور پیشفرض، فرمان sort این خط را به این نحو میبیند که دو فیلد وجود دارد؛ اولین فیلد، حاوی کاراکترهای William و دومین فیلد حاوی کاراکترهای Shotts میباشد (توجه داشته باشید که فاصله میان آنها نیز جز فیلد دوم است).
با نگاهی به یکی از خطوط خروجی ls مشاهده خواهیم کرد که خطی حاوی هشت فیلد بود که فیلد پنجم آن، اندازه فایل است.
1 |
-rwxr-xr-x 1 root root 8234216 2012-04-07 17:42 inkscape |
برای تمرینهای بعدی، فایلی را ایجاد میکنیم که تاریخچه توزیعهای رایج لینوکس را بین سالهای 2006 تا 2008 نشان میدهد. هر خط دارای سه فیلد است: فیلد نام توزیع، فیلد شماره نسخه و فیلد تاریخ انتشار؛ که آن را بهصورت زیر ایجاد خواهیم کرد:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
SUSE 10.2 12/07/2006 Fedora 10 11/25/2008 SUSE 11.0 06/19/2008 Ubuntu 8.04 04/24/2008 Fedora 8 11/08/2007 SUSE 10.3 10/04/2007 Ubuntu 6.10 10/26/2006 Fedora 7 05/31/2007 Ubuntu 7.10 10/18/2007 Ubuntu 7.04 04/19/2007 SUSE 10.1 05/11/2006 Fedora 6 10/24/2006 Fedora 9 05/13/2008 Ubuntu 6.06 06/01/2006 Ubuntu 8.10 10/30/2008 Fedora 5 03/20/2006 |
سپس با استفاده از فرمان sort آن را مرتب میکنیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[me@linuxbox ~]$ sort distros.txt Fedora 10 11/25/2008 Fedora 5 03/20/2006 Fedora 6 10/24/2006 Fedora 7 05/31/2007 Fedora 8 11/08/2007 Fedora 9 05/13/2008 SUSE 10.1 05/11/2006 SUSE 10.2 12/07/2006 SUSE 10.3 10/04/2007 SUSE 11.0 06/19/2008 Ubuntu 6.06 06/01/2006 Ubuntu 6.10 10/26/2006 Ubuntu 7.04 04/19/2007 Ubuntu 7.10 10/18/2007 Ubuntu 8.04 04/24/2008 Ubuntu 8.10 10/30/2008 |
تقریبا کارد کرد! مشکل در مرتب کردن شماره نسخه فدورا است. از آنجایی که عدد 1 در مجموعه کاراکترها، قبل از اعداد 6 و 7 و 8 میآید؛ در نتیجه شماره 10 نیز که دارای عدد 1 است، پیش از موارد دیگر خواهد آمد، در صورتیکه میبایست در آخر همه، لیست شود.
برای حل چنین مشکلی باید چندیم کلمه را مرتب کنیم. درواقع ما میخواهیم یک مرتبسازی الفبایی را بر رو فیلد اول و سپس یک مرتبسازی عددی را بر روی فیلد دوم انجام دهیم. فرمان sort به چندین نمونه از گزینههای –k اجازه کار میدهد. بنابراین چندین کلید sort را میتوان اختصاص داد. در حقیقت ممکن است، یک کلید شامل محدودهای از فیلدها باشد.
در ادامه مثالی از مرتبسازی با چندین کلید را مشاهده میکنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[me@linuxbox ~]$ sort --key=1,1 --key=2n distros.txt Fedora 5 03/20/2006 Fedora 6 10/24/2006 Fedora 7 05/31/2007 Fedora 8 11/08/2007 Fedora 9 05/13/2008 Fedora 10 11/25/2008 SUSE 10.1 05/11/2006 SUSE 10.2 12/07/2006 SUSE 10.3 10/04/2007 SUSE 11.0 06/19/2008 Ubuntu 6.06 06/01/2006 Ubuntu 6.10 10/26/2006 Ubuntu 7.04 04/19/2007 Ubuntu 7.10 10/18/2007 Ubuntu 8.04 04/24/2008 Ubuntu 8.10 10/30/2008 |
با وجود اینکه ما به دلیل روشنتر شدن مطلب از فرم طولانی گزینه –key استفاده کردیم، اما گزینههای -k 1,1 -k 2n نیز دقیقا همان کار را انجام میدهند.
در اولین نمونه گزینه key محدودهای از فیلدها را اختصاص دادیم تا در کلید اول شامل شوند. از آنجایی که میخواهیم مرتبسازی فقط به فیلد اول محدود شود، 1,1 را لحاظ کردیم؛ بدین معنا که از فیلد اول شروع شود و در فیلد اول نیز پایان یابد.
در نمونه دوم از کلید، میخواهیم مرتبسازی عددی انجام شود. بنابراین گزینه –n را اضاف نمودیم که به معنای مرتبسازی عددی است. همانطور که میبینید، بهجای –n مقدار 2n را با گزینه ادغام کردیم.
فیلد سوم در لیست ما، حاوی تاریخ در فرمتی نامناسب برای مرتبسازی است. در کامپیوترها، تاریخها معمولا با فرمت YYYY-MM-DD قرار میگیرند تا مرتبسازی تقویمی آسان شود. حال چگونه این نوع فرمت (یعنی YYYY-MM-DD) مرتب شود؟
خوشبختانه فرمان sort راهی برای مرتبسازی فراهم میکند. گزینه key به مشخصههای فیلدها این اجازه را میدهد تا فیلدها را درون فیلدها تعریف کنیم:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[me@linuxbox ~]$ sort -k 3.7nbr -k 3.1nbr -k 3.4nbr distros.txt Fedora 10 11/25/2008 Ubuntu 8.10 10/30/2008 SUSE 11.0 06/19/2008 Fedora 9 05/13/2008 Ubuntu 8.04 04/24/2008 Fedora 8 11/08/2007 Ubuntu 7.10 10/18/2007 SUSE 10.3 10/04/2007 Fedora 7 05/31/2007 Ubuntu 7.04 04/19/2007 SUSE 10.2 12/07/2006 Ubuntu 6.10 10/26/2006 Fedora 6 10/24/2006 Ubuntu 6.06 06/01/2006 SUSE 10.1 05/11/2006 Fedora 5 03/20/2006 |
با اختصاص -k 3.7 به فرمان sort از کلید مرتبسازی استفاده میشود که در کاراکتر هفتم درون فیلد سوم شروع شود که برای ما سال را نشان خواهد داد.
همینطور -k 3.1 و -k 3.4 ماه و روز را جدا کرده و مرتب میکند. علاوه بر آن، گزینههای –n و –r را اضافه کردیم تا مرتبسازی عددی بهصورت معکوس انجام شود. گزینه –b نیز بهمنظور سرکوب کردن فاصلههای آغازین اضافه شده است.
برخی از فایلها از Tabها و فاصلهها، بهمنظور جداکننده استفاده نمیکنند. بهعنوان مثال /etc/passwd را مشاهده کنید:
1 2 3 4 5 6 7 8 9 10 11 |
[me@linuxbox ~]$ head /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/bin/sh bin:x:2:2:bin:/bin:/bin/sh sys:x:3:3:sys:/dev:/bin/sh sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/bin/sh man:x:6:12:man:/var/cache/man:/bin/sh lp:x:7:7:lp:/var/spool/lpd:/bin/sh mail:x:8:8:mail:/var/mail:/bin/sh news:x:9:9:news:/var/spool/news:/bin/sh |
فیلدها در این فایل، با استفاده از کاراکتر (:) از هم جدا شدهاند. بنابراین چگونه میتوانیم این فایلها را با استفاده از فیلد کلید جدا کنیم؟ فرمان sort گزینه –t را برای ما به ارمغان آورده تا از طریق آن بتوانیم کاراکتر جداکننده فیلدها را تعریف کنیم. برای مرتبسازی فایل passwd در فیلد هفتم، بهصورت زیر عمل خواهیم کرد:
1 2 3 4 5 6 7 8 9 10 |
[me@linuxbox ~]$ sort -t ':' -k 7 /etc/passwd | head me:x:1001:1001:Myself,,,:/home/me:/bin/bash root:x:0:0:root:/root:/bin/bash dhcp:x:101:102::/nonexistent:/bin/false gdm:x:106:114:Gnome Display Manager:/var/lib/gdm:/bin/false hplip:x:104:7:HPLIP system user,,,:/var/run/hplip:/bin/false klog:x:103:104::/home/klog:/bin/false messagebus:x:108:119::/var/run/dbus:/bin/false polkituser:x:110:122:PolicyKit,,,:/var/run/PolicyKit:/bin/false pulse:x:107:116:PulseAudio daemon,,,:/var/run/pulse:/bin/false |
درباره فرشید نوتاش حقیقت
همیشه نیازمند یک منبع آموزشی فارسی در حوزه نرمافزارهای آزاد/ متنباز و سیستمعامل گنو/لینوکس بودم. از این رو این رسالت رو برای خودم تعریف کردم تا رسانه «محتوای باز» رو بوجود بیارم.
نوشتههای بیشتر از فرشید نوتاش حقیقتاین سایت از اکیسمت برای کاهش هرزنامه استفاده می کند. بیاموزید که چگونه اطلاعات دیدگاه های شما پردازش میشوند.
دیدگاهتان را بنویسید