LoginSignup
0
0

【学習】Linuxコマンド Day8

Posted at

おさらい

前回まで学習したことはこちらです。

今日学ぶこと

  • フィルタについて
  • テキスト処理のコマンド

フィルタ

フィルタとは標準入力から標準出力へ出力を行うプログラムを指す。
例として、catコマンド、headコマンド、tailコマンドなど。
head、tailコマンドはわかりやすく、標準入力からデータを受け取り、先頭や末尾だけ出力する。
フィルタを通し、元のテキストを加工してゆくことをテキスト処理という。
頻回に使用するコマンドを説明、実践してみる。

テキスト処理のコマンド

行数、単語数を出力する(wcコマンド)

/etc/crontabに対し、行数、単語数、バイト数を表示してみる。

$ wc /etc/crontab
15 84 451 /etc/crontab

左から行数、単語数、バイト数となるがオプションをつけることで単独で表示が可能。
-l 行
-w 単語
-c バイト数

行単位で並び変えて出力する(sortコマンド)

特定の規則に従って並び替えるためにはsortコマンドを使用する。
まずはオプション無しでアルファベット順に並び替える。

$ cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash

sortコマンドを使用すると

$ sort /etc/shells
/bin/bash
/bin/sh
/usr/bin/bash
/usr/bin/sh

アルファベット順に並び替えられたことが確認できた。
続いて複数列からなるテキストを並び替える場合だがわかりやすくまず「fileA」と「fileB」をtouchコマンドで作成した。

$ ls -l
-rw-rw-r--. 1 imagata imagata 0 Sep 13 18:00 fileA
-rw-rw-r--. 1 imagata imagata 0 Sep 13 18:01 fileB

この状態からファイル名を基準に(9列目)並び替えを行う。-kオプションを使用する。

$ ls -l | sort -k9 -r
-rw-rw-r--. 1 imagata imagata 0 Sep 13 18:01 fileB
-rw-rw-r--. 1 imagata imagata 0 Sep 13 18:00 fileA

-rオプションを使用したが、9列目にアルファベットの逆順なのでfile「B」から「A」の順で出力される。

入力の重複を取り除く(uniqコマンド)

まず次のようなファイルを用意した。(fileC)

red
red
blue
yellow
blue

uniqコマンドを使用することで重複する行を取り除くことができる

$ uniq fileC
red
blue
yellow
blue

しかし、blueが重複するのにも関わらず取り除かれていない。
これはredは連続した行となっていたが。blueはyellowを挟んで重複しているからである。
このように連続している場合でないとuniqコマンドを使用しても取り除けない。
そこでsortコマンドも使用することで並び替え後(重複する行が存在する場合は連続する形にした後)に取り除くことが可能。

$ sort fileC | uniq
red
blue
yellow

sortコマンドの-uオプションでも同様となる。

$ sort -u fileC 
red
blue
yellow

重複回数のカウント(uniqコマンド -cオプション)

今度は-cオプションを使用することで重複回数を調べることができる。

$ sort fileC | uniq -c
2 blue
2 red 
1 yellow

重複回数をもとに並び替えてみる

$ sort fileC | uniq -c | sort -n
1 yellow
2 blue
2 red 

テキスト処理後保存を行う(リダイレクト)

上記のようにフィルタで処理を行ってもファイルそのものが変更されるわけではないので、結果を保存したいときはリダイレクトを使用する。

$ sort fileC | uniq -c > fileD
$ cat fileD
1 yellow
2 blue
2 red 

入力の文字を置換して出力する(trコマンド)

trコマンドを使用することで文字を置き換えることが可能。
試しにアルファベットの小文字を大文字にしてみる。

$ cat fileC | tr a-z A-Z
RED
RED
BLUE
YELLOW
BLUE

trコマンドは引数にファイルを指定できないのでこのようにcatコマンドとパイプラインを駆使することが望ましい。

指定した文字列を含む行を出力する(grepコマンド)

一部の行のみ取り出したい場合、grepコマンドを使用する。
grepコマンドは1文字ずつではなく、文字列単位で検索を行う。
以下は"bash"を含む行のみ出力した場合。

$cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
$ grep bash /etc/shells
/bin/bash
/usr/bin/bash

指定した列のみ出力する(awkコマンド)

awkコマンドを使用すると指定した列だけ出力が可能。
今回はfileA,fileBが存在する場合から左から6番目(〇月)の部分のみ取り出す。

$ ls -l
-rw-rw-r--. 1 imagata imagata 0 Sep 13 18:00 fileA
-rw-rw-r--. 1 imagata imagata 0 Sep 13 18:01 fileB
$ls -l | awk '{print $6}'
Sep
Sep

複数列取り出すことも可能。
例:パーミッションと月

$ ls -l
-rw-rw-r--. 1 imagata imagata 0 Sep 13 18:00 fileA
-rw-rw-r--. 1 imagata imagata 0 Sep 13 18:01 fileB
$ls -l | awk '{print $1,$6}'
-rw-rw-r--. Sep
-rw-rw-r--. Sep

おつかれさまでした

とても感覚的なことではありますが、Enterを押して実行する前に結果が予測でき、パイプラインを使用することにもだんだんと慣れてきた気がします。
実際に求める情報に対してコマンド、オプションを駆使して速やかに結果が得ることができるように練習していきたいと思います。
ただし、少し気を抜くとリダイレクト・・・?のようにぱっと出てこないことももちろんあるのでもやもやと中途半端な理解だと感じる箇所は自分の記事も見直して記憶に定着させたいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0