-
Notifications
You must be signed in to change notification settings - Fork 11
/
bolum8.tex
772 lines (637 loc) · 44.6 KB
/
bolum8.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
\chapter{Standart G/Ç ve Filtre Komutları}
\label{chap:bolum8}
\paragraph{Amaçlar}{
\begin{itemize}
\item Kabuk G/Ç yönlendirmelerinde uzmanlaşmak
\item En önemli filtre komutlarını öğrenmek
\end{itemize}
}
\paragraph{Önceden Bilinmesi Gerekenler}{
\begin{itemize}
\item Kabuk işlemleri
\item Metin düzenleyicisi kullanımı (Bölüm ~\ref{chap:bolum3})
\item Dosya ve dizin kullanma (Bölüm ~\ref{chap:bolum6})
\end{itemize}
}
\begin{section}{G/Ç Yönlendirmeleri ve Komut Boru Hatları}
\begin{subsection}{Standart Kanallar}
Çoğu Linux komutu - grep ve Bölüm ~\ref{chap:bolum7}'deki arkadaşları gibi - girdi verilerini okumak, bir şekilde düzenlemek ve bu düzenlemenin sonucunu çıktı olarak vermek üzerine tasarlanmıştır. Örnek olarak, eğer aşağıdaki gibi bir komut girerseniz;
\footnotesize
\begin{verbatim}
$ grep xyz
\end{verbatim}
\normalsize
Klavyeden metin girdisi yapabilirsiniz ve grep sadece “xyz” harf grubunu içeren kısımları vurgulayacaktır.
\footnotesize
\begin{verbatim}
$ grep xyz
abc def
xyz 123
xyz 123
aaa bbb
YYYxyzZZZ
YYYxyzZZZ
Ctrl + d
\end{verbatim}
\normalsize
(Sondaki klavye tuş kombinasyonu grep'e girdi girişinin bittiğini haber verir.)
grep “standart girdiden” verileri okur – bu durumda klavyeden – ve bunu “standart çıktıya” yazar – bu koşulda konsol ekranına ya da yüksek ihtimalle görsel bir arayüzdeki bir terminal programına –. Bu standart yolların üçüncüsü “standart hata çıktısı”dır; grep' in ürettiği veriler standart çıktıya verilirken, standart hata çıktısı hata mesajlarını alır. (Örneğin, bulunmayan bir girdi dosyası ya da düzenli ifadelerdeki bir yazım hatası gibi)
Bu bölümde bir programın standart çıktısını nasıl bir dosyaya yönledirebileceğini ya da başka bir programın standart girdisini nasıl bir dosyadan alabileceğini öğreneceğiz. Daha da önemlisi, bir programın çıktısını direk olarak (dosyaya yönlendirmek gibi bir ara yöntem kullanmadan) nasıl başka bir dosyanın girdisi olarak kullanabileceğinizi öğreneceksiniz. Bu, tek başlarına düşünüldüklerinde hepsi oldukça basit olan Linux komutlarının birleşerek daha karmaşık yapılar oluşturmalarına olanak sağlar. (Bunu bir Lego seti gibi düşünün.)
Bu bölümde bu konuyu derinlemesine incelemeyeceğiz. Çok karmaşık kabuk betikleri oluşturmak için sıradaki rehberi, İleri Düzey Linux, okuyun, o rehberde Unix araçları kullanılarak kabuk için betikler oluşturmak anlatılmaktadır. Bu bölümde komut satırında temel Linux komutlarının zekice birleştirilmesini öğreneceksiniz.
\begin {table}[htb]
\caption {Linux'ta Standart Kanallar} \label{tab:8.1}
\begin{tabular}{c l l l l}
\hline
Kanal & İsim & Kısaltma & Aygıt & Kullanım Alanı\\
\hline
0 & standart girdi & stdin & klavye & Programların girdisi\\
1 &standart çıktı& stdout& ekran& Programın çıktısı\\
2 &standart hata cıktısı & stderr & ekran & Programın hata mesajları \\
\hline
\end{tabular}
\end {table}
Standart kanallar Tablo 8.1 de gösterilmiştir. Tabloda belirtilen stdin, stdout ve stderr standart girdi, standart çıktı ve standart hata çıktısı için olan teknik terimlerdir. Bu yollar daha sonra kullanacağımız gibi sırasıyla 0, 1 ve 2 numaralarına atanmışlardır.
Kabuk, bahsedilen program hiçbir şeyi fark etmeden, ayrı komutlar için bu standart kanalları yönlendirebilir. Çıktı ekranda ya da terminal penceresi dışında belirtilen bir dosyada yazıyor olabilir, ancak uygulamalar her zaman bu standart kanlları kullanır. Bu dosya başka bir cihaz olabileceği gibi (yazıcı gibi) çıktıyı alacak metin dosyasını belirlemek mümkündür. Dosyanın o anda varolması bile gerekmez, gerektiği zaman kendiliğinden oluşturulur.
Standart girdi yolu da aynı şekilde yönlendirilebilir. Bir program girdisini klavyeden değil belirtilen bir dosyadan (bu başka bir aygıt ya da dosya olabilir) alır.
\footnotesize
Klavye ve çalıştığınız terminal ekranı (ister Linux konsolu olsun, ister seri porttaki bir terminal, ister görsel arayüzde çalışan bir terminal penceresi, isterse de güvenli kabuk olarak bilinen ağdan bağlanılan bir oturum olsun) /dev/tty dosyası ile erişilebilir – veri okumak isteniyorsa bu klavye, cıktı vermek isteniyorsa bu ekran olarak kullanılır (tersi bayağı saçma olurdu). Şu komut:
\begin{verbatim}
$ grep xyz /dev/tty
\end{verbatim}
\normalsize
Bu bölümde önceden verdiğimiz grep komutuna denktir. Bu konuyla ilgili daha fazla bilgiyi Bölüm ~\ref{chap:bolum10}'da “özel dosyalar”da bulabilirsiniz.
\end{subsection}
\begin{subsection}{Standart Kanalları Yönlendirmek}
Standart çıktı kanalı “$>$” (büyüktür işareti) operatörü kullanılarak yönlendirilebilir. Aşağıdaki örnekte, “ls -laF” komutunun çıktısı filelist adı verilen bir dosyaya yönlendirilmektedir; ekran çıktısı şöyle gözükür:
\footnotesize
\begin{verbatim}
$ ls -laF >filelist
$ _
\end{verbatim}
\normalsize
Eğer filelist dosyası mevcut değilse oluşturulur. Ancak eğer bu isimde bir dosya varsa dosyanın üzerine yazılır. Kabuk bunu bahsedilen program çalıştırılmadan önce ayarlar – komut çağrısında yazım hataları varsa ya da program hiç çıktı oluşturmasa bile yine de çıktı dosyası oluşturulur. (bu durumda filelist dosyası boş olacaktır)
Eğer kabuk çıktı yönlendirmelerinde varolan dosyaların üzerine yazılmasını engellemek istiyorsanız, “set -o noclobber” komutu verilerek varolan dosyalar korunabilir. Bu durumda, eğer çıktı varolan bir dosyaya yönlendirilirse bir hata oluşacaktır.
Filelist dosyasına her zamanki yollarla bakabilirsiniz, mesela less kullanarak:
\footnotesize
\begin{verbatim}
$ less filelist
total 7
drwxr-xr-x 12 joe users 1024 Aug 26 18:55 ./
drwxr-xr-x 5 root root 1024 Aug 13 12:52 ../
drwxr-xr-x 3 joe users 1024 Aug 20 12:30 photos/
-rw-r--r-- 1 joe users 0 Sep 6 13:50 filelist
-rw-r--r-- 1 joe users 15811 Aug 13 12:33 pingu.gif
-rw-r--r-- 1 joe users 14373 Aug 13 12:33 hobby.txt
-rw-r--r-- 2 joe users 3316 Aug 20 15:14 chemistry.txt
\end{verbatim}
\normalsize
Eğer filelist dosyasının içeriğine dikkatlice bakarsanız, filelist adında boyutu 0 olan bir dizin girdisi görebilirsiniz. Bu kabuğun çalışma şeklinden kaynaklanır: Kabuk, komut satırını işlerken önce çıktı yönlendirmesini fark eder ve yeni bir filelist dosyası oluşturur (ya da varolan dosyanın içeriğini siler). Komutun (bu örnekte ls) standart çıktısını terminal yerine filelist dosyasına bağlayarak komutu çalıştırır.
ls çıktısındaki dosyanın uzunluğu 0 görünür çünkü ls, filelist dosyası ile ilgili bilgiye dosyaya hiçbir şey yazılmadan önce bakar, filelist satırından önce üç dosya olmasına rağmen. Bunun nedeni ls'nin önce bütün dizin girdilerini okuyup, bunları dosya adına göre sıralamasından ve ancak bunları tamamladıktan sonra dosyaya yazmaya başlamasıdır. Bu sebeple ls sadece yeni oluşturulmuş (ya da içi boşaltılmış) filelist dosyasını görür.
Eğer bir komutun çıktısını varolan bir dosyaya dosyanın önceki içeriğini değiştirmeden eklemek istiyorsanız $>>$ operatörünü kullanabilirsiniz. Eğer dosya yoksa, bu durumda da oluşturulacaktır.
\footnotesize
\begin{verbatim}
$ date >> filelist
$ less filelist
total 7
drwxr-xr-x 12 joe users 1024 Aug 26 18:55 ./
drwxr-xr-x 5 root root 1024 Aug 13 12:52 ../
drwxr-xr-x 3 joe users 1024 Aug 20 12:30 photos/
-rw-r--r-- 1 joe users 0 Sep 6 13:50 filelist
-rw-r--r-- 1 joe users 15811 Aug 13 12:33 pingu.gif
-rw-r--r-- 1 joe users 14373 Aug 13 12:33 hobby.txt
-rw-r--r-- 2 joe users 3316 Aug 20 15:14 chemistry.txt
Wed Oct 22 12:31:29 CEST 2003
\end{verbatim}
\normalsize
Bu örnekte, on anki tarih ve saat filelist dosyasına ekleniyor.
Bir komutun standart çıktısını yönlendirmenin bir başka yolu geri imlerdir (`\ldots`) Bu işlem \textbf{komut değiştirme} olarak da adlandırılır. Geri imlerin içindeki bir komutun standart çıktısı geri imler arasındaki komut (ve geri im işaretleri) ile değiştirilerek komut satırına eklenir ve değişiklikten sonraki komut çalıştırılır.
Örneğin:
\footnotesize
\begin{verbatim}
$ cat dates
22/12 Get presents
23/12 Get Christmas tree
24/12 Christmas Eve
$ date +%d/%m
23/12
$ grep `date +%d/%m` dates
23/12 Get Christmas tree
\end{verbatim}
\normalsize
” `date` “ yerine daha uygun bir yazım \$(date) kullanmaktır. Bu yöntem, iç içe geçmiş bu tip değiştirme çağrılarını daha kolay yazmayı sağlar. Bununla birlikte bu söz dizimi sadece bash gibi modern kabuklar tarafından desteklenir.
Standart girdi kanalını yönlendirmek için $<$ işaretini (küçüktür işareti) kullanabilirsiniz. Bu, klavye girdisi yerine belirtilen dosyanın içeriğini okuyacaktır.
\footnotesize
\begin{verbatim}
$ wc -w <frog.txt
1397
\end{verbatim}
\normalsize
Bu örnekte, wc filtre komutu frog.txt dosyasındaki kelimeleri sayar.
Birden fazla girdi dosyasını birleştirmek için $<<$ gibi bir yönlendirme bulunmaz, bunu yapmak için cat komutunu kullanmanız gerekir.
\footnotesize
\begin{verbatim}
$ cat file1 file2 file3 | wc -w
\end{verbatim}
\normalsize
(“\textbar” operatörü ile ilgili daha geniş bilgiyi gelecek bölümde anlatacağız.) Ancak çoğu program bir ya da birden fazla dosya ismini komut satırı girdisi olarak kabul eder.
Elbette, standart girdi ve standart çıktı aynı anda eş zamanlı olarak yönlendirilebilir. Aşağıdaki örnekte kelime sayacının çıktısı wordcount olarak adlandırılan bir dosyaya yazılır.
\footnotesize
\begin{verbatim}
$ wc -w <frog.txt >wordcount
$ cat wordcount
1397
\end{verbatim}
\normalsize
Standart girdi ve standart çıktı kanalları dışında ayrıca standart hata çıktısı kanalı bulunur. Eğer bir programın çalışmasında hatalar meydana gelirse, buna karşılık gelen mesajlar bu kanala yazılır. Böylece standart çıktıyı dosyaya yönlendirdiğiniz zaman bile hata mesajlarını görebilirsiniz. Eğer standart hata çıktısının da bir dosyaya yazılmasını istiyorsanız yönlendirme operatörünü kullanırken kanal numarasını belirtmelisiniz - stdin (0$<$ ) ve stdout (1$>$) için bu isteğe bağlı bir seçenektir fakat stderr için (2$>$) yazımını kullanmak zorunludur. $>$\& operatörünü her iki çıktıyı da yazdırmak için kullanabilirsiniz.
\footnotesize
\begin{verbatim}
make >make.log 2>&1
\end{verbatim}
\normalsize
Bu komut make komutunun standart çıktısını ve standart hata çıktısını make.log dosyasına yönlendirir.
\paragraph{Dikkat}{Burada sıralama çok önemlidir. Aşağıdaki iki komut tümüyle farklı sonuçlar oluşturur. İkinci durumda standart hata çıktısı standart çıktı nereye giderse oraya yönlendirilecektir (/dev/tty, standart çıktının gittiği yer), sonra standart çıktı make.log'a gönderilir ama bu standart hata çıktısının gideceği yönü değiştirmez.}
\footnotesize
\begin{verbatim}
make >make.log 2>&1
make 2>&1 >make.log
\end{verbatim}
\normalsize
\paragraph{{\Huge{\PencilLeftDown}}Alıştırmalar}{
\begin{enumerate}
\item -U seçeneğini ls komutunun çıktısını sıralamadan vermesi için kullanabilirsiniz. “ls -laU $>$filelist ” yazmanızdan sonra bile dosya içerisindeki çıktıda filelist dosyasının boyutu 0 olarak gözükür. Bunun nedeni ne olabilir?
\item “ls /tmp” ve “ls /tmp $>$ls-tmp.txt” komutlarının çıktılarını karşılaştırınız. Bir fark görüyor musunuz? Eğer fark varsa bunu nasıl açıklarsınız?
\item Neden bir dosyayı bir adımda yeni haliyle değiştirmek mümkün değildir? Mesela “grep xyz file $>$ file” neden mümkün değildir?
\item “cat foo $>>$foo ” komutunda foo'nun boş bir dosya olmadığını varsayarsak bu komuttaki sorun nedir?
\item Kabukta, bir hata mesajını nasıl standart hata çıktısı olarak alırsınız?
\end{enumerate}}
\end{subsection}
\begin{subsection}{Komut Boru Hatları}
Çıktı yönlendirmesi bir programın sonucunu kaydederek başka bir komutta işlemek için sıkça kullanılır. Bununla birlikte bu çeşit ara kayıtlar çok sıkıcı sayılmazlar ama işleri bittiği zaman silmeyi unutmamak gerekir. Bu sebeple, Linux komutları birbirine doğrudan borularla bağlama yöntemi sunar: Bir programın çıktısı otomatik olarak başka bir programın girdisi olur.
Birkaç komutun arasındaki yönlendirmeler \textbar operatörü kullanılarak yapılır. “ls -laF” komutunun çıktısını bir dosyaya yönlendirip sonra bu dosyaya less kullanarak bakmak yerine, aynı işlemi tek adımda ara dosya kullanmadan yapabilirsiniz:
\footnotesize
\begin{verbatim}
$ ls -laF | less
total 7
drwxr-xr-x 12 joe users 1024 Aug 26 18:55 ./
drwxr-xr-x 5 root root 1024 Aug 13 12:52 ../
drwxr-xr-x 3 joe users 1024 Aug 20 12:30 photos/
-rw-r--r-- 1 joe users 449 Sep 6 13:50 filelist
-rw-r--r-- 1 joe users 15811 Aug 13 12:33 pingu.gif
-rw-r--r-- 1 joe users 14373 Aug 13 12:33 hobby.txt
-rw-r--r-- 2 joe users 3316 Aug 20 15:14 chemistry.txt
\end{verbatim}
\normalsize
Bu komut yönlendirmeleri neredeyse istenilen herhangi bir uzunlukta olabilir. Ayrıca en sonda oluşacak olan sonuç bir dosyaya yönlendirilebilir:
\begin{verbatim}
$ cut -d: -f1 /etc/passwd | sort | pr -2 >userlst
\end{verbatim}
Bu komut yönlendirmesi bütün kullanıcı isimlerini /etc/passwd dosyasının : ile ayrılan ilk sütunundan alıp bunları alfabetik şekilde sıralayıp sonucu iki sütun halinde userlst dosyasına yazar. Burada kullanılan komutlar bölümün devamında açıklanacaktır.
Bazen veri akışını bir komut yönlendirmesi içindeki ara bir noktada depolamak gerekebilir, örneğin bir devredeki ara sonuç başka görevler için kullanışlı olabilir. tee komutu veri akışını kopyalar ve bir kopyayı standart çıktıya diğerini ise bir dosyaya gönderir. Komut ismi tesisatçılıkta aynı şekilde kullanılan bir tür borudan esinlenmiştir (Tablo ~\ref{tab:8.2}'ye bakın).
Hiç seçenek belirtilmediğinde tee komutu belirtilen dosyayı oluşturur ya da böyle bir dosya varsa üzerine yazar; -a (ingilizcede birleştirme anlamına gelen “append”) seçeneği kullanılarak varolan dosyaya ekleme yapılabilir.
\footnotesize
\begin{verbatim}
$ ls -laF | tee list | less
total 7
drwxr-xr-x 12 joe users 1024 Aug 26 18:55 ./
drwxr-xr-x 5 root root 1024 Aug 13 12:52 ../
drwxr-xr-x 3 joe users 1024 Aug 20 12:30 photos/
-rw-r--r-- 1 joe users 449 Sep 6 13:50 content
-rw-r--r-- 1 joe users 15811 Aug 13 12:33 pingu.gif
-rw-r--r-- 1 joe users 14373 Aug 13 12:33 hobby.txt
-rw-r--r-- 2 joe users 3316 Aug 20 15:14 chemistry.txt
\end{verbatim}
\normalsize
Bu örnekte içinde çalışılan dizinin içeriği hem list dosyasına hem de ekrana yazılır. (list dosyası ls komutunun çıktısında görünmez çünkü tee komutu dosyayı ls komutunun çalıştırılmasından sonra oluşturur.)
\paragraph{{\Huge{\PencilLeftDown}}Alıştırmalar}{
\begin{enumerate}
\item Aynı ara sonucu birden fazla dosyaya aynı anda nasıl yazardınız?
\end{enumerate}}
\end{subsection}
\end{section}
\begin{section}{Filtre Komutları}
Unix' in - ve dolayısı ile Linux'un - temel fikirlerinden biri ``araç takımı'' ilkesidir. Sistem, her biri (kavramsal olarak) basit bir görevi yerine getiren çok sayıda sistem programı ile birlikte gelir. Bu programlar başka programları oluşturmak için “inşa blokları” olarak kullanılabilir ve böylece programcıları gerekli fonksiyonları kendi başlarına geliştirme derdinden kurtarır. Örnek olarak, programlar kendi sıralama yöntemini içermek yerine Linux'un onlara sağladığı sort komutunu kullanır. Bu modüler yapı birkaç avantaja sahiptir:
\begin{itemize}
\item Bütün zamanlarını yeni sıralama fonksiyonları üretmekle harcaması gerekmeyen programcıların hayatını kolaylaştırır.
\item Eğer sort bir hata düzeltmesi veya performans iyileştirmesi geçirirse, sort kullanan bütün programlar bundan faydalanır – ve çoğu durumda programlarda herhangi bir değişiklik yapılması bile gerekmez.
\end{itemize}
Girdilerini standart girdiden alıp çıktılarını standart çıktıya veren araçlara “filtre komutları” ya da kısaca “filtreler” denir. Girdi yönlendirmesi olmazsa filtre komutu, girdisini klavyeden okuyabilir. Klavye girişinin bittiğini belirtmek için terminal tarafından “dosya sonu” olarak algılanılan \Ctrl + \keystroke{d} tuş kombinasyonunu kullanmalısınız.
Bunun sadece klavye girdisi için geçerli olduğunu unutmayın. Diskteki dosya \Ctrl + \keystroke{d} karakterini (ASCII 4) içerebilir ve sistem bunun dosyanın sonu olduğunu düşünmez. Bu davranış Ctrl-Z (ASCII 26) karakterinin bir metin dosyası içinde bile olsa garip anlam içerdiği oldukça popüler bir işletim sisteminin davranışının tersidir.
“Normal” komutların çoğu, önceden belirtilmiş olan grep gibi, eğer üzerinde çalışacakları bir dosya ismi belirtilmezse filtreler gibi çalışır.
Bu bölümün geri kalanında bu şekilde çalışan çoğu önemli komuta aşina hale geleceksiniz. Bazı komutlar tam olarak filtre komutları sayılmasa da, boru hatları için önemli bloklar oluşturmakta kullanılırlar.
\begin {table}[Htb]
\caption {cat seçenekleri} \label{tab:8.2}
\begin{tabular}{c p{9cm}}
\hline
Seçenek & Sonuç\\
\hline
-b & (ing. number non-blank lines) Çıktıdaki boş olmayan tüm satırları 1'den başlayarak numaralandırır. \\
-E & (ing. end-of-line) Her satırın sonunda \$ işareti gösterir (Satır sonundaki boşluk karakterlerini yakalamak için faydalıdır).\\
-n & (ing. number) Çıktıdaki tüm satırları 1'den başlayarak numaralandırır.\\
-s & (ing. squeeze) Çıktıdaki art arda gelen boş satırları tek bir boş satır ile değiştirir.\\
-T & (ing. tabs) d “\textbar”.\\
-v & (ing. visible) “M-a”.\\
-A & (ing. show all) -vET ile aynı.\\
\hline
\end{tabular}
\end {table}
\end{section}
\begin{section}{Dosyaları Okuma ve Yazma}
\begin{subsection}{Metin Dosyalarının Çıktıları ve Birleştirme - cat}
cat (ing. "concatenate": bitiştirmek) komutu gerçekte komut satırından ismi verilen birden fazla dosyayı tek bir dosyada birleştirmek için kullanılır. Eğer sadece bir dosya ismi belirtirseniz, bu dosyanın içeriği standart çıktıya yazılacaktır. Eğer hiç dosya ismi belirtmezseniz cat standart girdiyi okur - bu kullanışsız görünebilir ama cat satırları numaralandırma, satırları sonlarını ve özel karakterleri görünür yapma ya da birden fazla boş satırı teke indirme gibi seçenekler sunar. (Tablo ~\ref{tab:8.2})
Söylemeye gerek olmasa bile belirtmekte yarar var, cat sadece metin dos\-ya\-la\-rın\-da anlaşılır sonuçlar ortaya çıkarır. Eğer bu komutu diğer çeşit dosyalar için kullanırsanız (mesela /bin/cat gibi bir ikili dosya için) çıktı tamamlandığında kabuk iletisinin - en azından bir metin terminalinde - okunamayan karakterlerden oluşması kesin gibidir. Bu durumda normal karakter kümesini (çıktıyı görmeden yazmak zorunda kalabilirsiniz) \textbf{reset} komutu ile geri getirebilirsiniz. Eğer cat çıktısını bir dosyaya yönlendirirseniz bu sorunla tabii ki karşılaşmazsınız.
"En Kullanışsız cat Kullanımı Ödülü" cat'i gereksiz yere kullanan insanlara verilmelidir. Çoğu durumda komutlar sadece standart girdiyi okumakla kalmaz, dosya isimlerini de kabul eder, bu sebeple cat tek bir dosyayı standart girdiden bu komutlara göndermek için gerekli değildir. “cat data.txt \textbar grep foo” gibi bir komut gereksizdir çünkü bunun yerine basitçe “grep foo data.txt” yazabilirsiniz. Hatta grep sadece standart girdiden okuyabiliyor olsaydı bile “grep foo $<$data.txt ” daha kısa olurdu ve ayrıca cat sürecine ihtiyaç olmazdı.
\paragraph{{\Huge{\PencilLeftDown}}Alıştırmalar}{
\begin{enumerate}
\item Bir dizinin “garip” isimlere sahip dosyalara sahip olduğunu nasıl kontrol edebilirsiniz (örneğin isminin sonunda bir boşluk karakteri olan ya da ortasında görünmez kontrol karakteri bulunduranlar gibi)?
\end{enumerate}}
\end{subsection}
\begin{subsection}{Başlangıç ve Bitiş - head ve tail}
Bazen dosyanın sadece bir parçasıyla ilgilenirsiniz: Doğru dosya olup olmadığını görmek için ilk birkaç satır ya da özellikle kayıt dosyalarında son birkaç satır. Head ve tail komutları tam olarak bunu verirler - varsayılan olarak argümanlar arasında verilen dosyaların her birinin ilk on ve son on satırını (veya alışıldığı gibi standart girdilerinin ilk veya son 10 satırını) gös\-te\-rir\-ler. -n seçeneği gösterilecek satır sayısını değiştirmenizi sağlar: “head -n 20” ilk yirmi satırı değer olarak döndürürken “tail -n 5 data.txt” data.txt dosyasının son beş satırını döndürür.
Geleneksel olarak istediğimiz n sayıdaki satırı direk olarak ”-n” şeklinde belirtebiliz. Resmi olarak bu yönteme artık izin verilmiyor ancak head ve tail' in Linux versiyonları hala bu özelliği destekliyorlar.
-c seçeneğini sayma işleminin satır olarak değil byte olarak yapılması için kullanabilirsiniz: “head -c 20” standart girdinin ne kadar satıra sahip olursa olsun ilk 20 bytelık kısmını gösterir. Eğer “b”, “k”, ya da “m” harflerini eklerseniz (sırasıyla bloklar, kibibytelar ve mebibytelar) sayım 512, 1024 ya da 1048576 ile çarpılarak yapılır.
head ayrıca eksi işaretini kullanmanıza izin verir: “head -c -20 ” standart girdinin son 20 bytelık kısmı hariç tümünü gösterir.
head' in bu münasebetsizliğine karşılık, tail de head'in desteklemediği bir şey yapar: eğer satır numaraları “+” ile başlıyorsa, verilen satırdan itibaren bütün verileri görüntüler.
\begin{verbatim}
$ tail -n +3 file satır 3 ve sonrasındakiler
\end{verbatim}
tail komutu ayrıca önemli olan -f seçeneğini destekler. Bu seçenek tail komutunun dosyanın o anki sonunu yazdırmasının ardından dosyaya daha sonra eklenecek olan satırları da yazdırması için beklemesini sağlar. Bu yöntem bazı kayıt dosyalarını gözetlemek istediğiniz zaman çok işe yarar. Eğer tail -f komutuna birden fazla dosya ismi verirseniz, her çıktı satırı bloğu için hangi dosyaya yeni veri eklendiğini gösteren bir başlık satırı koyar.
\paragraph{{\Huge{\PencilLeftDown}}Alıştırmalar}{
\begin{enumerate}
\item Standart girdinin sadece 13. satırını nasıl çıktı olarak alabilirsiniz?
\item “tail -f” komutunu deneyin: Bir dosya oluşturun ve bu dosya üzerinde “tail -f” komutunu çalıştırın. Sonra başka bir pencereden ya da sanal bir konsoldan dosyaya bir şeyler ekleyin (örneğin echo $>>$ ... kullanarak) ve tail komutunun çıktısını gözlemleyin. Tail birden fazla dosyayı aynı anda eşzamanlı olarak izlediğinde nasıl bir çıktı veriyor?
\item İzlenen dosya küçülürse “tail -f” komutuna ne olur?
\item Aşağıdaki komutların çıktısını açıklayın:
\begin{verbatim}
$ echo Hello >/tmp/hello
$ echo "Hiya World" >/tmp/hello
\end{verbatim}
İlk echo komutundan sonra aşağıdaki komutu başka bir pencerede ça\-lış\-tır\-dı\-ğı\-nız\-da ne olur?
\begin{verbatim}
$ tail -f /tmp/hello
\end{verbatim}
\end{enumerate}}
\end{subsection}
\end{section}
\begin{section}{Veri Yönetimi}
\begin{subsection}{Sıralı Dosyalar - sort ve uniq}
sort komutu metin dosyaları içindeki satırları önceden belirtilmiş bir kritere göre sıralamaya yarar. Varsayılan ayar her satırın ilk birkaç karakterinin ASCII karakter seti değerlerine\footnote{Elbette ASCII sadece 128 karakter içerir. Burada aslında ASCII ile beraber 128'den sonraki karakter kodları için kullanılmakta olan uzantı (örn: ISO-8859-1 veya diğer adıyla ISO-Latin-1) kastedilmektedir.} göre artan şekilde (A-Z) sıralanmasıdır. Almancadaki üzeri çift noktalı karakterlerin sıklıkla hatalı sıralanmasının sebebi budur. Örneğin, “Ä” nın karakter kodu 143'tür, bu yüzden sıralamada karakter kodu 91 olan “Z” karakterinden sonra gelir. Küçük “a” karakteri bile büyük “Z” karakterinden "daha büyük" sayılır.
Elbette sort değişik dillere ve kültürlere göre davranabilir. Alman kurallarına göre sıralama yapmak için LANG, LC\_ALL ya da LC\_COLLATE çevre değişkenlerinden birini “de”, “de\_DE” ya da “de\_DE@UTF-8” (seçiminiz kullandığınız dağıtıma göre değişir) olarak değiştirebilirsiniz. Eğer kullandığınız sıralama kurallarını sadece bu defaya mahsus değiştirmek istiyorsanız aşağıdaki şekilde kullanabilirsiniz:
\begin{verbatim}
$ ... | LC_COLLATE=de_DE.UTF-8 sort
\end{verbatim}
LC\_ALL değeri LC\_COLLATE üzerinde üstündür. Aynı şekilde LC\_COLLATE de LANG değerinden üstündür. Ayrıca Alman sıralama düzeni kullanmanın bir yan etkisi de sıralama yaparken harflerin boyutunun göz önüne alınmamasıdır.
Aksini belirtmezseniz, sıralama bütün girdi satırı göz önüne alınarak alfabetik göre yapılır. Yani iki satırın ilk karakterleri eşitse satırdaki ilk değişiklik gösteren karakter sıralamayı belirler. Elbette sort sadece bütün satıra göre değil, özelleştirilmiş bir şekilde belirli sütunlara ya da (hayali) bir tablonun alanlarına göre sıralama yapabilir. Alanlar 1'den başlayarak numaralandırılır, "-k 2" ile sıralama için ilk alan görmezden gelinerek her satırın ikinci alanı dikkate alınır. Eğer iki satırın ikinci alanları eşitse ve “-k 2,3” şeklinde daha özelleştirilmiş bir seçenek belirlenmediyse satırın kalanına bakılır. Ayrıca aynı sort komutunda birden fazla -k seçeneği belirtilebilir.
Bunlara ek olarak, sort artık kullanılmayan eski bir sıralama belirtecini de destekler: Alanlar sıfırdan başlayarak numaralandırıldığında ilk alan “+m” ve son alan “-n” olarak belirtilir. Ayrıca son alan açıkça belirtilmelidir. Üstteki örnek “+1 ”, “+1 -3 ” ve “+1 -2 ” şeklinde yazılabilir.
Boşluk karakteri alanlar arasında ayırıcı işlevi görür. Eğer art arda birden fazla boşluk varsa sadece ilki ayırıcı olarak değerlendirilir; geri kalanlar takip eden alana ait değerler olarak kabul edilir. Örnek olarak Lameborough Track and Field Club'ın düzenlediği yıllık maratonun katılımcılarının isimlerinden oluşan bir listeyi ele alalım. Başlangıç olarak ilgili çevre değişkenlerini sıfırlayarak sistemin standart dil ortamının (“POSIX”) kullanıldığından emin oluruz. (4. sütun koşucunun forma numarasıdır.)
\footnotesize
\begin{verbatim}
$ unset LANG LC_ALL LC_COLLATE
$ cat participants.dat
Smith Herbert Pantington AC 123 Men
Prowler Desmond Lameborough TFC 13 Men
Fleetman Fred Rundale Sportsters 217 Men
Jumpabout Mike Fairing Track Society 154 Men
de Leaping Gwen Fairing Track Society 26 Ladies
Runnington Vivian Lameborough TFC 117 Ladies
Sweat Susan Rundale Sportsters 93 Ladies
Runnington Kathleen Lameborough TFC 119 Ladies
Longshanks Loretta Pantington AC 55 Ladies
O'Finnan Jack Fairing Track Society 45 Men
Oblomovsky Katie Rundale Sportsters 57 Ladies
\end{verbatim}
\normalsize
Önce soyadına göre sıralamayı deneyelim. Bu aslında kolay bir örnek çünkü soyadı kısmı zaten her satırın başında:
\footnotesize
\begin{verbatim}
$ sort participants.dat
Fleetman Fred Rundale Sportsters 217 Men
Jumpabout Mike Fairing Track Society 154 Men
Longshanks Loretta Pantington AC 55 Ladies
O'Finnan Jack Fairing Track Society 45 Men
Oblomovsky Katie Rundale Sportsters 57 Ladies
Prowler Desmond Lameborough TFC 13 Men
Runnington Kathleen Lameborough TFC 119 Ladies
Runnington Vivian Lameborough TFC 117 Ladies
Smith Herbert Pantington AC 123 Men
Sweat Susan Rundale Sportsters 93 Ladies
de Leaping Gwen Fairing Track Society 26 Ladies
\end{verbatim}
\normalsize
Listedeki iki küçük sorunu fark etmiş olmalısınız: “Oblomovsky” “O’Finnan” ın önünde olmalıydı ve “de Leaping” listenin sonunda değil başında yer almalıydı. Eğer sıralama kuralları olarak “İngilizce”yi belirtirsek bu sorunlar kaybolur:
\footnotesize
\begin{verbatim}
$ LC_COLLATE=en_GB sort participants.dat
de Leaping Gwen Fairing Track Society 26 Ladies
Fleetman Fred Rundale Sportsters 217 Men
Jumpabout Mike Fairing Track Society 154 Men
Longshanks Loretta Pantington AC 55 Ladies
Oblomovsky Katie Rundale Sportsters 57 Ladies
O'Finnan Jack Fairing Track Society 45 Men
Prowler Desmond Lameborough TFC 13 Men
Runnington Kathleen Lameborough TFC 119 Ladies
Runnington Vivian Lameborough TFC 117 Ladies
Smith Herbert Pantington AC 123 Men
Sweat Susan Rundale Sportsters 93 Ladies
\end{verbatim}
\normalsize
(en\_GB “İngiliz İngilizcesi” için, en\_US ise “Amerikan İngilizcesi” için kullanılan kısaltmadır ve her ikisi de burada aynı işi görür) Şimdi ilk isme göre sıralama yapalım:
\footnotesize
\begin{verbatim}
$ sort -k 2,2 participants.dat
Smith Herbert Pantington AC 123 Men
Sweat Susan Rundale Sportsters 93 Ladies
Prowler Desmond Lameborough TFC 13 Men
Fleetman Fred Rundale Sportsters 217 Men
O'Finnan Jack Fairing Track Society 45 Men
Jumpabout Mike Fairing Track Society 154 Men
Runnington Kathleen Lameborough TFC 119 Ladies
Oblomovsky Katie Rundale Sportsters 57 Ladies
de Leaping Gwen Fairing Track Society 26 Ladies
Longshanks Loretta Pantington AC 55 Ladies
Runnington Vivian Lameborough TFC 117 Ladies
\end{verbatim}
\normalsize
Bu örnek sort'un yukarıda anlatılan özelliğini gösterir: İlk tanımlanan boşluk ayırıcı olarak kabul edilir, diğerleri takip eden alanın değerlerini oluşturur. Gördüğünüz gibi ilk isimlerden sadece soyisimleri aynı uzunlukta olanlar alfabetik olarak listelendi. Bu durum -b seçeneği kullanılarak düzeltilebilir, bu seçenek art arda gelen boşluk karakterlerini tek bir boşluk olarak değerlendirir.
\footnotesize
\begin{verbatim}
$ sort -b -k 2,2 participants.dat
Prowler Desmond Lameborough TFC 13 Men
Fleetman Fred Rundale Sportsters 217 Men
Smith Herbert Pantington AC 123 Men
O'Finnan Jack Fairing Track Society 45 Men
Runnington Kathleen Lameborough TFC 119 Ladies
Oblomovsky Katie Rundale Sportsters 57 Ladies
de Leaping Gwen Fairing Track Society 26 Ladies
Longshanks Loretta Pantington AC 55 Ladies
Jumpabout Mike Fairing Track Society 154 Men
Sweat Susan Rundale Sportsters 93 Ladies
Runnington Vivian Lameborough TFC 117 Ladies
\end{verbatim}
\normalsize
Bu sıralı liste hala biraz hatalı; bunun için 8.14 numaralı alıştırmaya bakın.
Aşağıdaki örnekte de görüldüğü gibi sıralama alanı daha detaylı bir şekilde belirtilebilir:
\footnotesize
\begin{verbatim}
$ sort -br -k 2.2 participants.dat
Sweat Susan Rundale Sportsters 93 Ladies
Fleetman Fred Rundale Sportsters 217 Men
Longshanks Loretta Pantington AC 55 Ladies
Runnington Vivian Lameborough TFC 117 Ladies
Jumpabout Mike Fairing Track Society 154 Men
Prowler Desmond Lameborough TFC 13 Men
Smith Herbert Pantington AC 123 Men
de Leaping Gwen Fairing Track Society 26 Ladies
Oblomovsky Katie Rundale Sportsters 57 Ladies
Runnington Kathleen Lameborough TFC 119 Ladies
O'Finnan Jack Fairing Track Society 45 Men
\end{verbatim}
\normalsize
Burada participants.dat dosyası ikinci alanın ikinci karakterine göre, yani ilk adlarının ikinci karakterine göre (çok anlamlı!) azalan şekilde (-r) sıralanmıştır. Bu örnekte de başta gelen boşluklar -b seçeneği kullanılarak göz ardı edilmelidir. (Örnek 8.14 teki hata burada da kendini tekrar ediyor.)
-t seçeneği ile ("terminate", Türkçesi “durdur”) alan ayırıcısının olarak istenen bir karakteri seçebilirsiniz. Bu seçenek alanlar zaten veri olarak boşluklar içerebileceği için iyi bir fikir olabilir. Aşağıda örnek dosyamızın için daha kullanışlı (ancak daha zor okunan) bir hali bulunuyor:
\footnotesize
\begin{verbatim}
Smith:Herbert:Pantington AC:123:Men
Prowler:Desmond:Lameborough TFC:13:Men
Fleetman:Fred:Rundale Sportsters:217:Men
Jumpabout:Mike:Fairing Track Society:154:Men
de Leaping:Gwen:Fairing Track Society:26:Ladies
Runnington:Vivian:Lameborough TFC:117:Ladies
Sweat:Susan:Rundale Sportsters:93:Ladies
Runnington:Kathleen:Lameborough TFC:119:Ladies
Longshanks:Loretta: Pantington AC:55:Ladies
O'Finnan:Jack:Fairing Track Society:45:Men
Oblomovsky:Katie:Rundale Sportsters:57:Ladies
\end{verbatim}
\normalsize
“LC\_COLLATE=en\_GB sort -t: -k2,2” kullanılarak ilk isme göre sıralamak artık doğru sonucu veriyor. Ayrıca katılımcının numarasına göre sıralamak (4 numaralı alan) kulüp isminde kaç tane boşluk olursa olsun daha kolaydır:
\footnotesize
\begin{verbatim}
$ sort -t: -k4 participants0.dat
Runnington:Vivian:Lameborough TFC:117:Ladies
Runnington:Kathleen:Lameborough TFC:119:Ladies
Smith:Herbert:Pantington AC:123:Men
Prowler:Desmond:Lameborough TFC:13:Men
Jumpabout:Mike:Fairing Track Society:154:Men
Fleetman:Fred:Rundale Sportsters:217:Men
de Leaping:Gwen:Fairing Track Society:26:Ladies
O'Finnan:Jack:Fairing Track Society:45:Men
Longshanks:Loretta: Pantington AC:55:Ladies
Oblomovsky:Katie:Rundale Sportsters:57:Ladies
Sweat:Susan:Rundale Sportsters:93:Ladies
\end{verbatim}
\normalsize
Elbette “sayı” sıralaması aksi belirtilmedikçe alfabetik olarak yapılır – “117” ve “123” “13” ten önce, o da "154"den önce gelir. Bu durum sayısal karşılaştırma yapmaya zorlayan -n seçeneği ile düzeltilebilir.
\footnotesize
\begin{verbatim}
$ sort -t: -k4 -n participants0.dat
Prowler:Desmond:Lameborough TFC:13:Men
de Leaping:Gwen:Fairing Track Society:26:Ladies
O'Finnan:Jack:Fairing Track Society:45:Men
Longshanks:Loretta: Pantington AC:55:Ladies
Oblomovsky:Katie:Rundale Sportsters:57:Ladies
Sweat:Susan:Rundale Sportsters:93:Ladies
Runnington:Vivian:Lameborough TFC:117:Ladies
Runnington:Kathleen:Lameborough TFC:119:Ladies
Smith:Herbert:Pantington AC:123:Men
Jumpabout:Mike:Fairing Track Society:154:Men
Fleetman:Fred:Rundale Sportsters:217:Men
\end{verbatim}
\normalsize
sort'un bazı önemli seçenekleri Tablo ~\ref{tab:8.3}'te gösterilmiştir, ayrıca programın belgelerini incelemek de faydalı olabilir. Sort size çok zaman kazandırabilecek çok yönlü ve güçlü bir komuttur.
\footnotesize
\begin {table}[Htb]
\caption {sort seçenekleri} \label{tab:8.3}
\begin{tabular}{p{2cm} p{3cm} p{6cm}}
\hline
Seçenek & & Sonuç\\
\hline
-b & (boşluk, ing. blank) & Alanların içindeki başta gelen boşluk karakterlerini dikkate almaz.\\
-d & (sözlük, ing. dictionary) & Sözlük sırasına göre sıralar, örn. sadece harf, rakam ve boşluk karakterleri dikkate alınır.\\
-f & (katla, ing. fold) & Büyük ve küçük harfleri eşit olarak değerlendirir.\\
-i & (yoksay, ing. ignore) & Yazdırılamayan karakterleri dikkate almaz.\\
-k alan1 [, alan2] & (anahtar, ing. key) & alan1'den başlayıp alan2'ye kadar (dahil) sıralar.\\
-n & (sayısal, ing. numeric) & Alanın içeriğini sayı olarak kabul eder ve sayısal değerine göre sıralar, başta gelen boşluklar dikkate alınmaz.\\
-o & (çıktı, ing. output) & Sonuçları dosyaya yazdır, dosya ismi orjinal girdi dosyası ile aynı olabilir.\\
-r & (ters, ing. reverse) & Azalan şekilde sırala, örn: Z'den A'ya doğru\\
-t \textless karakter \textgreater & (durdur, ing. terminate) & Alan ayıracı olarak karakteri kullan.\\
-u & (Tekil, ing. unique) & Art arda gelen aynı çıktı satırlarından sadece ilkini yaz.\\
\hline
\end{tabular}
\end {table}
\normalsize
uniq komutu girdide verilen art arda gelen aynı satırların sadece ilkini (veya tercihinize göre sonuncusunu) yazdırmak gibi önemli bir işlev sağlar. Neyin “aynı” olarak kabul edileceği her zamanki gibi özel seçenekler kullanılarak değiştirilebilir. Uniq gördüğümüz komutların çoğundan farklıdır, bir tane dışında isteğe bağlı girdi dosyası kabul etmez; eğer ikinci bir dosya ismi verilirse bunu çıktının yazdırılacağı dosya olarak farz eder (eğer ikinci dosya ismi verilmezse çıktı standart çıktıya yazılır). uniq çağrısında hiç dosya ismi verilmemişse, beklendiği gibi standart girdiden okumaya başlar.
Uniq girdi dosyasındaki tüm eşit satırlar art arda sıralanmış olduğunda en iyi şekilde çalışır. Eğer durum bu değilse her bir satırın çıktıda sadece bir kez görüneceği kesin olmaz.
\footnotesize
\begin{verbatim}
$ cat uniq-test
Hipp
Hopp
Hopp
Hipp
Hipp
Hopp
$ uniq uniq-test
Hipp
Hopp
Hipp
Hopp
\end{verbatim}
\normalsize
Bunu “sort -u” komutunun çıktısıyla karşılaştırın:
\footnotesize
\begin{verbatim}
$ sort -u uniq-test
Hipp
Hopp
\end{verbatim}
\normalsize
\paragraph{{\Huge{\PencilLeftDown}}Alıştırmalar}{
\begin{enumerate}
\item participants0.dat dosyasındaki (alanların ":" ile ayrıldıkları dosya) katılımcı listesini klüp isimlerine ve her klüpteki oyuncuları da soyad ve ilk adlarına göre (bu sıra ile) sıralayın.
\item Katılımcı listesini klüp isimlerine göre artan bir şekilde (a-z) klüplerin oyuncularını da numaralarına göre azalan şekilde nasıl sıralarız? (İpucu: Sort programının belgelerini inceleyin!)
\item Örneklerde sürekli iddia ettiğimiz hata nedir ve hangi sebepten dolayı oluşur?
\item Aşağıdaki dosya isimlerine sahip bir dizin:
\footnotesize
\begin{verbatim}
01-2002.txt 01-2003.txt 02-2002.txt 02-2003.txt
03-2002.txt 03-2003.txt 04-2002.txt 04-2003.txt
<<<
11-2002.txt 11-2003.txt 12-2002.txt 12-2003.txt
\end{verbatim}
\normalsize
ls komutunun çıktısını tarihsel sıraya göre doğru dizen sort komutunu yazın:
\footnotesize
\begin{verbatim}
01-2002.txt
02-2002.txt
<<<
12-2002.txt
01-2003.txt
<<<
12-2003.txt
\end{verbatim}
\normalsize
\end{enumerate}}
\end{subsection}
\begin{subsection}{Sütunlar ve Alanlar - cut, paste vb.}
Grep ile bir metin dosyası içindeki satırları bulup kesebilirken cut komutu bir metin dosyasında sütun yönelikli çalışır. İki farklı çalışma yöntemi vardır:
Birinci ihtimal sütunların kesin bir şekilde ayrılmış olmasıdır. Bu sütunlar bir satırda tek bir karaktere karşılık gelirler. Bu gibi sütunları kesmek için -c (ing. column) seçeneği ile sütun numarası verilmelidir. Birden fazla sütunu tek seferde kesmek için sütun numaraları virgül ile ayrılır. Sütun aralıkları bile belirtilebilir.
\footnotesize
\begin{verbatim}
$ cut -c 12,1-5 participants.dat
SmithH
ProwlD
FleetF
JumpaM
de LeG
\end{verbatim}
\normalsize
Bu örnekte ilk ismin ilk karakteri ve son ismin beş karakteri ayrılır. Ayrıca çıktının her zaman için girdideki sütunlar ile aynı sıraya göre gerçekleştiğini görebiliriz. Eğer seçilmiş sütun sıraları birbirleri üstüne gelse bile, her girdi karakteri sadece bir defa yazdırılır:
\footnotesize
\begin{verbatim}
$ cut -c 1-5,2-6,3-7 participants.dat
Smith
Prowler
Fleetma
Jumpabo
de Leap
\end{verbatim}
\normalsize
İkinci yöntem bir ayraç karakteri ile ayrılmış göreceli alanları kesmektir. Eğer bu göreceli alanları kesmek istiyorsanız cut, -f (ing. field) seçeneğine ve istenen alan numarasına ihtiyaç duyar. Sütunlar için geçerli olan kuralların hepsi alanlar içinde geçerlidir. -c ve -f seçenekleri birbirine karşılıklıdır, aynı anda her ikisini birden kullanamazsınız.
Varsayılan ayırıcı tab karakteridir, diğer ayırıcılar -d (ing. delimiter) seçeneği ile belirtilebilir:
\footnotesize
\begin{verbatim}
$ cut -d: -f 1,4 participants0.dat
Smith:123
Prowler:13
Fleetman:217
Jumpabout:154
de Leaping:26
\end{verbatim}
\normalsize
Bu yolla katılımcıların soyadları (birinci sütun) ve numaraları (dördüncü sütun) listeden alınır. Yukarıdaki örnekte okunabilirlik için çıktının sadece ilk birkaç satırı gösterilmektedir.
Sözü açılmışken, --output-delimeter seçeneğini kullanarak çıktı alanları için girdi ayıracından farklı bir ayırıcı belirleyebilirsiniz:
\footnotesize
\begin{verbatim}
$ cut -d: --output-delimiter=': ' -f 1,4 participants0.dat
Smith: 123
Prowler: 13
Fleetman: 217
Jumpabout: 154
de Leaping: 26
\end{verbatim}
\normalsize
Eğer gerçekten sütun ya da alanların sırasını değiştirmek istiyorsanız, awk ve perl gibi büyük silahları ortaya çıkarmak zorundasınız. Bunu şimdi anlatacağımız paste komutu ile yapabilirsiniz ama bu biraz can sıkıcı olabilir.
Dosyalar sütunlar yerine alanlara göre işlenecekse -s (ing. seperator, ayırıcı) seçeneği kullanışlı olur. “cut -f” ayırıcı karakterini içermeyen satırları bulduğunda çıktıya bunları bütün halinde verir; -s bu satırları gizler.
Paste komutu belirtilen dosyalardaki satırları birleştirir, bu nedenle sıklıkla cut komutu ile birlikte kullanılır. Hemen fark edeceğiniz gibi paste bir filtre komutu değildir. Yine de dosya adı gelmesi gereken yere “-” işaretini koyarak paste komutunun dosya yerine standart girdiden okumasını sağlayabilirsiniz. Komutun çıktısı daima standart çıktıya gönderilir.
Söylediğimiz gibi, paste satır satır çalışır. Eğer iki dosya adı belirtildiyse ilk dosyanın ilk satırı ve ikincinin ilk satırı (bir tab karakterini ayırıcı olarak kullanarak) çıktının ilk satırı olacak şekilde birleştirilir. Aynı işlem dosyadaki bütün satırlar için tekrarlanır. Başka bir ayırıcı kullanmak için -d seçeneğini kullanabilirsiniz.
Örnek olarak; maraton koşucuları listesini katılım numaraları öne gelecek birleştirip yeni bir dosya oluşturabiliriz:
\footnotesize
\begin{verbatim}
$ cut -d: -f4 participants0.dat >number.dat
$ cut -d: -f1-3,5 participants0.dat \
>
| paste -d: number.dat - >p-number.dat
$ cat p-number.dat
123:Smith:Herbert:Pantington AC:Men
13:Prowler:Desmond:Lameborough TFC:Men
217:Fleetman:Fred:Rundale Sportsters:Men
154:Jumpabout:Mike:Fairing Track Society:Men
26:de Leaping:Gwen:Fairing Track Society:Ladies
117:Runnington:Vivian:Lameborough TFC:Ladies
93:Sweat:Susan:Rundale Sportsters:Ladies
119:Runnington:Kathleen:Lameborough TFC:Ladies
55:Longshanks:Loretta: Pantington AC:Ladies
45:O'Finnan:Jack:Fairing Track Society:Men
57:Oblomovsky:Katie:Rundale Sportsters:Ladies
\end{verbatim}
\normalsize
Bu dosya “sort -n p-number.dat” kullanılarak numaralara göre düzgn bir şekilde sıralanabilir.
-s (seri, ing. serial) ile verilen dosyalar sırayla işlenir. İlk olarak, ilk dosyanın bütün satırları (aralarında bir ayırıcı karakter bulunacak şekilde) tek bir satır haline getirilir ve sonra ikinci dosyadaki bütün satırlar çıktının ikinci satırını oluştururlar.
\footnotesize
\begin{verbatim}
$ cat list1
Wood
Bell
Potter
$ cat list2
Keeper
Chaser
Seeker
$ paste -s list*
Wood Bell Potter
Keeper Chaser Seeker
\end{verbatim}
\normalsize
list* arama karakteriyle eşleşen bütün dosyalar - bu durumda list1 ve list2 - paste kullanılarak birleştirildi. -s seçeneği bu dosyaların tüm satılarlarının çıktının bir sütununu oluşturmasını sağlar.
\paragraph{{\Huge{\PencilLeftDown}}Alıştırmalar}{
\begin{enumerate}
\item participants.dat dosyasının (eşit uzunlukta sütunlar halinde olanının) katılımcı numarası ve kulüplerinin olmadığı bir halini oluşturunuz.
\item participants0.dat dosyasının (: işaretinin ayırıcı olarak kullanıldığı halinin) katılımcı numarası ve kulüplerinin olmadığı bir halini oluşturunuz.
\item Katılımcılar0.dat dosyasının alanlarının “:” ile değil “,\textvisiblespace ” (virgül ve boşluk işareti) ile ayrıldığı bir halini oluşturunuz.
\item Sisteminizde kaç tane grup kullanıcılar tarafından birincil grup olarak kullanılıyor? (Kullanıcıların birincil grupları /etc/passwd dosyasındaki dördüncü alandadır.)
\end{enumerate}}
\paragraph{Bu Bölümdeki Komutlar}{
\begin{itemize}
\item[cat]Dosyaları birleştirir (diğer işlevlerin yanında)
\item[cut]Girdisindeki sütun ya da alanları ayırır
\item[head]Bir dosyanın başlangıcını gösterir
\item[paste]Farklı girdi dosyalarındaki satırları birleştirir
\item[reset]Bir terminalin karakter kümesini mantıklı bir değere sıfırlar
\item[sort]Girdisini satır satır sıralar
\item[tail]Bir dosyanın sonunu gösterir
\item[uniq]Bir dosyadaki art arda gelen eş satırları teke indirir
\end{itemize}}
\paragraph{Özet}{
\begin{itemize}
\item Her Linux programı standart G/Ç yollarını, stdin, stdout ve stderr'i destekler.
\item Standart çıktı ve standart hata çıktısı $>$ ve $>>$ operatörleri ile, standart girdi $<$ operatörü ile yönlendirilebilir.
\item Boru hatları komutların standart çıktı ve girdilerini (ara dosyalar olmadan) direkt olarak bağlamak için kullanılabilir.
\item tee komutunu kullanarak yönlendirmelerdeki ara sonuçları dosyalarda saklayabiliriz.
\item Filtre komutları (ya da filtreler) kendi standart girdilerini okuyup değiştirip sonucu standart çıktıya yazarlar.
\item sort sıralama için kullanılan çok yönlü bir programdır.
\item cut komutu girdideki her satırdan belirtilen aralıktaki sütun ya da alanları ayırır.
\item paste ile dosyaların satırları birleştirilebilir.
\end{itemize}}
\end{subsection}
\end{section}