LINUXコマンド学習日記(2021/08/11) -草案

AWKの勉強用ファイルをコマンドラインから作ろうとして苦戦したので、できるまでに調べたこととかをまとめる。自分がたどった軌跡をそのまま書くので見るに堪えない。備忘録、感想文。

 

勉強用ファイルawkで操作する用のファイル。/usr/binディレクトリの中の普通のファイル(test -f でひっかかるタイプの(ディレクトリとか、リンクとかでない))の名前とサイズを並べたファイル。

 

1行コマンドラインでエレガントに作りたかったけど、到底できませんでした。

なので大きく4つのステップで実行していった。

  1. binディレクトリ配下のファイル名を抽出してまとめた一覧ファイルを作成する。
  2. 一覧ファイルを整形しgrepで使えるようにする。ファイル名の中に"["が有るのでその前にエスケープシーケンス"\"を入力する。あとファイル名が最後に来る行だけ抽出するように一覧ファイルの各行末に"$"を置く。
  3. 作成した一覧ファイルを使用してまたbinディレクトリにgrepをかける。それだけだとリンクまで引っかかってしまうから、行頭にlがついている行を省くgrepも一緒にかける。
  4. grepされた結果をawkコマンドを使ってファイル名とサイズの順で一行ずつファイルに出力する。

  3と4は一行で実行

 

 

1に関して

実行コマンド

for filepath in `find "$(pwd)" -type f`; do echo ${filepath##*/} >> ~/awk_pra/itiran.txt ;done

内容

現在地(/usr/bin)のファイルを"find -type f" でとってきてfor文に渡す。

${filepath##*/}はファイルパスからファイル名だけを取る変数展開の仕方。パターンの最長一致箇所を省く”~~/~~/~~/ファイル名”だと一番右の/までが最長一致でその部分を省くからファイル名が取得されることとなる。

↓のをそのまま使わせて頂いた。

パス文字列からファイル名などを抜き出す - Qiita

 

躓いたとこ

  • for分で一行ずつファイルに出力するときに">"を使うと最後の一行しか残らない。かといって">>"だと新規ファイルを作ってくれないのであらかじめファイルを作っておかないとだめ。なんかいいコマンドないかなぁ
  • 最初find -type fではなくて、if [ -f "$(pwd)/*" ]で一覧取得しようとしたけどどうしてもだめだった。(一気にディレクトリ内容を渡そうとしている?)

2に関して

やった事。vimでitiran.txtを開いて。"["を検索して見つかったところに"\"を置く。

あと書く行末に"$"を置く。←この操作はvimの機能で簡単にできた。

vimで複数行の行頭、行末に一気に文字を挿入する方法 - 基本へ帰ろう

 

3,4に関して

実行コマンド

ls -l | grep -v "\->" | grep -f ~/awk_pra/itiran.txt | awk '{print $9,$5}'

内容

一覧ファイルを使ってgrepする。しかしhostnameという名前のファイルが、普通ファイルの他にシンボリックリンク先にも設定されている(~~~~ -> hostnameとlsコマンドでは現れる)。そのせいでシンボリックリンクも拾ってきてしまっていたので、別のgrep を使用して"->"が現れる行を省くようにした。

あとはawkを使ってほしいフィールドを出力。

躓いたとこ

grep のオプションをlsと同じ用につなげて書くことが出来ると思い込んで、

grep -ev "\->" -ef itiran.txt みたいな記述をしようとしてたけどできなかった。grepは-eしか複数条件書くことが出来ない?不便だ。。。(不確定)

(普通にできました_2021/08/14)

grep -f [正規表現が書かれたファイル] -e[正規表現] [検索対象ファイル]

で検索対象のファイルに複数の正規表現で検索された結果が返ってきます。

manコマンドの見方も勉強した方がいいなこりゃ

 

総評

もっといろいろつまったとこあったけど、まとめる間に忘れていった。

shell芸極めた人だったら、自分がやりたいこと一行でできるんだろうな。