# পাইপলাইন

আমরা এপর্যন্ত ফাইল থেকে কমান্ড ও কমান্ড থেকে ফাইলে আউটপুট, এরর বা ইনপুট রিডিরেক্ট করেছি। এবার আমরা দেখবো একটি কমান্ডের স্ট্যান্ডার্ড আউটপুট কিভাবে অন্য একটি কমান্ড ইনপুট হিসেবে সরাসরি ব্যবহার করতে পারে। এই কাজটি করতে শেলে যে ফিচারটা থাকে তাকে বলে পাইপলাইন।

পাইপলাইন ব্যবহার করতে হয় '|' চিহ্ন দিয়ে। এর ব্যবহারিক কাঠামোটি এমন:

```
command1 | command2
```

আমরা এর আগে(1.3.2.stdordrct.md) `ls -l /usr/bin` কমান্ডের আউটপুট **ls-output.txt** এ রিডিরেক্ট করে **less** কমান্ড দিয়ে সেটা দেখেছি। পাইপলাইন ব্যবহার করে আমরা সহজেই কোনো ফাইলে এই আউটপুট রিডিরেক্ট না করে সরাসরি **less** কমান্ডেই রিডিরেক্ট করে দেখতে পারি এভাবে:

```
me@howtocode-pc:~$ ls -l /usr/bin/ | less
```

কমান্ডটি ব্যবহার করলে কোনো ফাইলে রিডিরেকশন ছাড়াই সরাসরি আপনাকে **less** এর মাধ্যমে স্ক্রীনে `ls-l /usr/bin` কমান্ডের আউটপুট দেখাবে।

### ফিল্টার

বেশ কিছু কমান্ড আছে যেগুলো ব্যবহার করে আমরা আউটপুটকে সাজাতে পারি কোনো বিশেষ নিয়মে। বা শুধু বিশেষ কোনো তথ্য বের করে আনতে পারি। এদের ফিল্টার বলে। আমরা এখন কয়েকটা ফিল্টার নিয়ে আলোচনা করবো।

#### sort

**sort** কমান্ডটি দিয়ে আমরা কোনো কমান্ডের আউটপুট বা টেক্সটফাইলের কমান্ডগুলোকে বিশেষ ক্রমে সাজাতে পারি। ডিফল্টভাবে এটি বর্ণানুক্রমিকভাবে সাজায়। একটা উদাহরণ দেখা যাক:

```
me@howtocode-pc:~$ ls /usr/bin/ /bin/ | sort | less
```

স্বাভাবিকভাবে যদি আমরা `ls /usr/bin /bin/` কমান্ডটি দিতাম তবে **/usr/bin/** ও **/bin/** ডিরেক্টরির কন্টেন্টের দুটি পৃথক লিস্ট আমরা পেতাম। আমরা যে আউটপুট পেতাম পাইপলাইন দিয়ে সেটা **sort** কমান্ডের কাছে পাঠানোর ফলে **sort** কমান্ড লিস্টদুটির আইটেমগুলি নিয়ে বর্ণানুক্রমে সাজিয়ে একটি লিস্ট বানিয়েছে। এই নতুন অখন্ড লিস্টকে আমরা আবার পাইপলাইনের মাধ্যমে **less** কমান্ড দিয়ে দেখেছি।

#### uniq

**uniq** কমান্ড দিয়ে ইউনিক আইটেম খুঁজে নিতে হয়। যেমন যদি আমরা আগের কমান্ডটি দিই বেশ কিছু ফাইল পাওয়া যাবে যা /usr/bin/ ও /usr/ উভয় ডিরেক্টরিতে আছে। আমরা যদি **sort** এর সাথে **uniq** কমান্ড পাইপলাইনে যোগ করি তবে যেসব আইটেম দুবার আছে তার থেকে একটা দেখাবে। এটা আমরা করতে পারি এভাবে:

```
me@howtocode-pc:~$ ls /usr/bin/ /bin/ | sort | uniq | less
```

আবার আমরা যদি চাই শুধু সেই সব আইটেমই দেখবো যা উভয় ডিরেক্টরিতেই আছে তবে তারজন্য আমরা uniq -d ব্যবহার করতে পারি এভাবে:

```
me@howtocode-pc:~$ ls /usr/bin/ /bin/ | sort | uniq -d | less
```

#### wc

**wc** কমান্ডটি দিয়ে কোনো আউটপুট বা টেক্সটের শব্দসংখ্যা গোনা যায়। আমরা যদি আগের কমান্ডটার শেষে less না দিয়ে wc -l কমান্ড ব্যবহার করি তাহলে আমরা শব্দসংখ্যা জানতে পারবো। স্ট্যান্ডার্ড ইনপুট থেকে গুনতে -l অপশন ব্যবহার করতে হয়। যেমন:

```
me@howtocode-pc:~$ ls /usr/bin/ /bin/ | sort | uniq | wc -l
2392
```

#### grep

**grep** কমান্ডটি ব্যবহার করা হয় টেক্সটের মধ্য থেকে বিশেষ প্যাটার্ন খুঁজে বের করে। এর কমান্ড কাঠামোটি এরকম:

```
grep pattern [file...]
```

এই কমান্ডটি পাইপলাইনে জুড়ে দিয়ে আমরা প্রয়জনীয় জিনিস খুঁজে নিতে পারি। /usr/bin ও /bin এর যে অখন্ড সর্টেড ইউনিক লিস্ট আমরা বানিয়েছিলাম তার মধ্য থেকে যেগুলোর নামের ভেতর 'zip' কথাটি আছে সেগুলো খুঁজে বের করতে পারি এভাবে:

```
me@howtocode-pc:~$ ls /usr/bin/ /bin/ | sort | uniq | grep zip
bunzip2
bzip2
bzip2recover
funzip
gpg-zip
gunzip
gzip
mzip
preunzip
prezip
prezip-bin
unzip
unzipsfx
zip
zipcloak
zipdetails
zipgrep
zipinfo
zipnote
zipsplit
```

#### head এবং tail

**head** এবং **tail** কমান্ড দিয়ে কোনো আউটপুটের যথাক্রমে প্রথম ও শেষ ১০ লাইন দেখা যায়। -n অপশন দিয়ে ঠিক করে দেয়া যায় কতগুলো লাইন দেখাবে। `ls /usr/bin/` কমান।ডের আউটপুটের প্রথম ১০ লাইন দেখতে পারি এভাবে:

```
me@howtocode-pc:~$ ls /usr/bin/ | head
[
2to3
2to3-2.7
2to3-3.4
411toppm
7z
7za
a2p
aclocal
aclocal-1.14
```

আবার মনে করুন একই কমান্ডের শেষের লাইন দেখতে চাই। কিন্তু ডিফল্টভাবে ১০টা দেখায় আমরা ৫টা দেখতে চাই। তাহলে লিখবো:

```
me@howtocode-pc:~$ ls /usr/bin/ | tail -n 5
zjsdecode
zlib-flate
zsoelim
zsync
zsyncmake
```

## tee

আমার যারা শহরে থাকি এবং যাদের অটোমেটেড মোটরচালিত পানি সরবরাহের ব্যবস্থা আছে তাদের বাড়িতে পানির পাইপের নেটওয়ার্ক দেখা যায়। আমরা এতক্ষন যে পাইপলাইনের কথা বলেছি তার সাথে এই পানি সরবরাহের নেটওয়ার্কের তুলনা করা যায়। তবে এতক্ষণ শুধু পাইপের পর পাইপজুড়ে লম্বা পাইপ তৈরি করা গেছে। আমরা পানি সরবরাহের নেটওয়ার্কে প্রায়ই 'T' এর মত দেখতে একধরনে সংযোগস্থল দেখি যেখান থেকে দুদিকে পানি সরবরাহ করা যায়। **tee** কমান্ডটিও একই কাজ করে। এর তিনটি পথ। একটি থেকে ইনপুট নেয় আর অন্য দুটির একটি থেকে আউটপুট টেক্সট ফাইলে পাঠায়। অপরটি দিয়ে স্ক্রীনে তথ্য পাঠায়। স্ক্রীনে পাঠানো তথ্যকে আমরা আবার পাইপলাইনের মাধ্যমে বিভিন্ন ফিল্টারে যুক্ত করতে পারি। একটা উদাহরণ দেখা যাক:

```
me@howtocode-pc:~$ ls /usr/bin/ | tee ls.txt | grep zip
funzip
gpg-zip
mzip
preunzip
prezip
prezip-bin
unzip
unzipsfx
zip
zipcloak
zipdetails
zipgrep
zipinfo
zipnote
zipsplit
```

কমান্ডটির শুরুতে আমরা `ls /usr/bin/` কমান্ড দিয়ে /usr/bin/ ডিরেক্টরি এর কন্টেন এর লিস্ট করেছি। তারপর সেটাকে পাইপলাইনের মাধ্যমে **tee** কমান্ডের সাথে যুক্ত করেছি। **tee** কমান্ডের আর্গুমেন্ট হিসেবে আমরা টেক্সট ফাইল ls.txt দিয়েছি। যার ফলে `ls /usr/bin/` এর আউটপুট ls.txt ফাইলে সেভ রাখবে। এরপর আমরা **tee** এর সাথে পাইপলাইনে **grep** কমান্ডটির সাথে আর্গুমেন্ট হিসেবে দিয়েছি zip। ফলে স্ক্রীনে শুধু সেইসব নাম দেখাবে যার নামের মধ্যে zip কথাটি আছে।
