UNIXコマンド テキスト処理を色々試してみた1
下記書籍に感化されて、UNIXのテキスト処理を色々試してみた。(環境は「Fedora環境をHyper-V上で構築&Telnetで接続まで メモ - oknknicの日記」で構築したFedora)
- 作者: Mike Gancarz,芳尾桂
- 出版社/メーカー: オーム社
- 発売日: 2001/02/01
- メディア: 単行本
- 購入: 40人 クリック: 498回
- この商品を含むブログ (145件) を見る
今回のトピックは以下の通り。
行の絞り込み - grep
例
#CSVの第3フィールドが「c」である行のみ表示 printf "a,b,c,d,e\nf,g,h,i,j" | grep -E '^([^,]*,){2}c[,]*' #CSVの第3フィールドに「Hoge」が含まれる行のみ表示 printf 'a,b,c,d,e\nf,g,IAmHoge!,i,j' | grep -E '^([^,]*,){2}[^,]*Hoge[^,]*'
#ディレクトリの特定の種類のものを一覧表示 #ディレクトリのみ ls -la | grep ^d #ファイルのみ ls -la | grep ^-
使いそうなオプション
- -E : 拡張正規表現(メタ文字 "+"、"?"、"|"の追加や、()等のメタ文字化)
- -v : マッチしない行のみ表示(inverse)
- -i : 大文字小文字を区別しない(ignore case)
- -B {行数} : マッチした行の前について、指定行数分表示
- -A {行数} : マッチした行の後について、指定行数分表示
- -c : ファイルごとにカウント(ただし、wcコマンドを使えば実現可能)
行の絞り込み(行番号指定も可能) - sed
例
#5行目のみ表示 seq 1 1 10 | sed -n '5p' #2〜5行目のみ表示 seq 1 1 10 | sed -n '2,5p' #2行目以降のみ表示 seq 1 1 10 | sed -n '2,$p'
なお、 sed は多機能なコマンドであるため、後日別日記で取り上げることにする。
列の選択 - cut
例
#文字番号(1以上)で指定 printf "01 02 03\n04 05 06" | cut -c 6-7 #区切り文字指定で、フィールド番号(1以上)指定 printf "item1,item2,item3\nitem4,item5,item6" | cut -d ',' -f 2
カウント - wc
# telnetを含むログの行数 cat /var/log/messages | grep telnet | wc -l
使いそうなオプション
- -l : 行数のみ表示
ソート - sort
例
#ソートされているかのチェックのみ実施。未ソートの場合はエラー表示+ステータス1 printf "01 02 03\n04 05 06" | cut -c 6-7 | sort -c #降順ソート printf "01 02 03\n04 05 06" | cut -c 6-7 | sort -r #区切り文字指定で、ソートキーのフィールド番号(1以上)指定(ただし、そのフィールドから行末までの文字列をソートキーとする) printf "item1,item4,item5,a\nitem2,item3,item5,b" | sort -t "," -k 2 #ファイル一覧を更新日時でソート(副次的に、更にファイル名でソート。なので ls -lrt とは異なる結果) ls -l | sort -t ' ' -k 6
その他 使いそうなオプション
- -f : 大文字小文字を区別しない
参考:ファイルリストのソート
とはいえ、ls結果のソートはlsのオプションでするのが楽でいいかもしれない。
#更新日時の降順 ls -lt #更新日時の昇順 ls -ltr
重複 - uniq
例
※あらかじめソート済みである必要がある
printf 'a hoge1 a\nb hoge2 b\nc hoge1 c\n' | sort -t ' ' -k 2 | uniq -f 1 -w 6 -c
使いそうなオプション
- -c : 各行の出現回数も表示
- -d : 重複行だけを表示
<キー指定>
- -f : 前から何フィールド目までをスキップした後をキーとするか(区切りは空白とタブ)
- -s : 前から何文字目までをスキップした後をキーとするか。fも指定した場合は、fの後
- -w : キー文字列の長さ(デフォルトは行末まですべて)(フィールドの前の区切り文字の長さも含む?)