コース内容#
データ抽出操作#
| コマンド | 機能 | コマンド | 機能 |
|:----:|:----|:----:|:----|:----:|:----|:----:|:----|
|cut | 分割 | grep | 検索 |
|sort | ソート | wc | 文字、単語、行数の統計 |
|uniq | 重複排除 | tee | 双方向リダイレクト |
|split | ファイル分割 | xargs | 引数置換 |
|tr | 置換、圧縮、削除 |    |    |
cut#
—— 包丁
- -d c 文字 c で分割
- "" または '' で c を囲むことができ、非常に柔軟
 - デフォルトはスペース
 
 - -f [n/n-/n-m/-m] 第 n ブロック / 第 n-end ブロック / 第 n-m ブロック / 第 1-m ブロックを選択
 - -b [n-/n-m/-m] バイト
 - -c [n-/n-m/-m] 文字
 
grep#
一般的な操作は:tldr grep
- -c 検索した回数をカウント [ファイル単位]
 - -n 行番号を順に出力
 - -v 一致しないものを出力 [補集合]
 - -C 3 周辺 3 行の内容を出力
 - -i 大文字小文字を区別しない
 - [PS] -n、-c は衝突し、-c の結果が優先される
 - 例
- パス内に doubleliu3 を含む行数をカウント

- cut+awk を使用するか、直接 awk を使用
 
 - hz 関連の実行中プロセスを確認

- ps -ef:Windows のタスクマネージャーに似ている
 - 比較すると、ps -aux は表示情報が多く、初期は UNIX システムに偏っている
 - [PS] ps -ef では、PPID は親プロセスの ID
 
 
 - パス内に doubleliu3 を含む行数をカウント
 
sort#
Excel のソート機能に似ており、デフォルトでは行の先頭に基づいて ASCII コードでソート
- -t 区切り文字、デフォルトは TAB
 - -k どの範囲でソートするか
 - -n 数値ソート
 - -r 逆順ソート
 - -u uniq [ただしカウントには不便]
 - -f 大文字小文字を無視 [デフォルト];-V [大文字小文字を無視しない]
 
【例】ユーザー情報を uid に基づいて数値ソート
cat /etc/passwd | sort -t : -k 3 -n
【テスト結果】
- ソート時はデフォルト
 - 特殊記号(アンダースコア "_"、"*"、"/" など)は省略される
 - 大文字小文字を無視し、ソート後は小文字が大文字の前に配置される [-V は大文字小文字を無視しない]
 
wc#
- -l 行数
 - -w 単語数
 - -m 文字数;-c バイト数
 
【例】
① 最近のシステムログインの総回数
last | grep -v "^$" | grep -v "begins" | wc -l
② PATH パスの関連統計:文字数、単語数、変数数、最後の変数を取得

uniq#
連続する重複のみが重複と見なされ、一般的には sort と組み合わせて使用される
- -i 大文字小文字を無視
 - -c カウント
 
【例】最近のユーザーのログイン回数をカウントし、回数の多い順にソート

tee#
端末に表示しつつ、ファイルに書き込む
- デフォルトでは元のファイルを上書き
 - -a 上書きせずに追加
 
【例】

split#
ファイルを分割し、大きなファイルの処理に適している
- -l num 行数で分割
 - -b size サイズで分割、512 [デフォルトバイト]、512k、512m
- 先頭行、末尾行が不完全な場合があるため、以下の方法を使用できる👇
 - ❗ -C size 最大 size サイズで分割し、行データを破壊しないことを保証!
 
 - -n num サイズに応じて num 分割
 
【例】/etc 下のファイルリストを 20 行ごとに分割してファイルを作成

xargs#
引数の置換、標準入力を受け取らないコマンドに適しており、コマンド置換の方法と同等
- -exxx "xxx" で終了
 

- -p 全体の指示を実行する前に確認
 - -n num 毎回受け取る引数の数を指定⭐、一度にすべてを渡すのではなく

- 単一の引数しか受け取れないコマンド [例:id] または関連するシーンに適している
 
 
tr#
標準入力の文字を置換、圧縮、削除し、tldr tr を参照できる
tr [オプション] < 文字 / 文字セット 1> < 文字 / 文字セット 2>
- デフォルトでは文字セット 1👉文字セット 2 に置換、一対一で対応
- 文字セット 1 が文字セット 2 より多い文字は、文字セット 2 の最後の文字で置換
 
 - -c 文字セット 1 に属さないすべての文字を文字 2 に置換
 - -s 圧縮し、連続する重複の文字 1👉1 つの文字 1 にする 【❗-c と組み合わせる場合は文字 2 に注意】
 - -d 文字セット 1 に属するすべての文字を削除
 - -t 文字セット 1 において文字セット 2 より多い文字を削除し、一対一で置換【❗ デフォルト方式との違いに注意】
 
【例】
①簡単な使用

- -s も引数が必要で、-c と組み合わせる場合はデフォルトで文字 2 を使用
 - -t は一対一で対応した文字のみを扱い、文字セット 1 が文字セット 2 より多い文字は無視する
 
②単語頻度の統計

- tr 置換👉ソート👉重複排除カウント👉ソート👉上位を表示
 
ソフトリンク、ハードリンク#
ハードリンクはストレージ使用量を減らし、ソフトリンクは inode とブロックが 1 つ増える
【背景紹介】
- ext4 ファイルシステム ——3 つの構成要素 ——inode、block、superblock
 - inode:ファイルノード
- 1 つの inode は 1 つのファイルに対応
 - ファイル情報 [ファイル権限、所有者、時間...] とファイルの実際の位置 [blocks 位置] を保存
 - blocks 位置が保存できない場合は、多層 blocks を使用
 
 - block:ファイルの実際の保存位置、1 つの block は一般的に 4096 バイト
 - superblock:少なくとも 2 つ、ファイルシステムの全体情報 [inode、block...] を保存
 
【ハードリンク】は別名に相当
- 元のファイルと同じ inode を持つ
 - ファイルの接続数 > 1
 - [PS]
- 別名を削除しても元のファイルには影響しない
 - 現在のディレクトリと親ディレクトリはハードリンクである [特別なディレクトリ]
 - ただし、ハードリンクはディレクトリをサポートせず、無限ループなどの問題が発生する可能性がある。参考:
- Why are hard links to directories not allowed in UNIX/Linux?——StackExchange
 - Why are hard links not allowed for directories?——StackExchange
 - linux ではなぜディレクトリのハードリンクができないのか?—— 知乎
 
 
 
【ソフトリンク】はショートカットに相当
- 新しいファイルを作成し、自分の inode を持ち、1 つの block [ファイルの実際の位置] を指す
 - ファイルタイプは link
 - [PS] ハードリンクよりも一般的に使用される
 
線形篩#
- 
 - 
shell の配列は初期化する必要はなく、最初は空である
- 実際には、どんな変数も最初は空で、型はない
 
 - 
【変数 x == x】の判空操作を学ぶ
 - 
配列のインデックスは変数名を直接使用でき、${} で囲む必要はない
 
【素数篩との効果比較】
2~20000 の素数の合計を求める
- 
 - 
shell では、素数篩ほどの効果は得られない。考えられる理由は:
- shell は多くのシステム呼び出しを含むため、純粋に数学的な観点からは見れない
 - shell スクリプトを実行すると CPU がフル稼働し、C 言語の効果とは比較できない
 - 割り算操作
 
 
➕SED スクリプト編集#
主にスクリプトを編集するために使用され、構文は vim を参考にできる
【一般的な操作】置換 [バッチ、行ごと、一致]、削除
# 各行で一致する最初の文字列パターンを置換 [正規表現をサポート]
sed 's/{{regex}}/{{replace}}/' {{filename}}
# 一致する行の最初の文字列を置換し、一致する行を削除
sed '/{{line_pattern}}/s/{{regex}}/{{replace}}/' {{filename}}
sed '/{{line_pattern}}/d' {{filename}}
# '#'などの他の区切り文字を使用でき、'/'文字を使用する必要があるシーンに対応
sed 's#{{regex}}#{{replace}}#' {{filename}}
# 2つの一致パターンの間のすべての行を削除
sed '/{{regex}}/,/{{regex}}/d' {{filename}}
# [特殊] 一致行の後/前の内容を削除
sed '/{{regex}}/,$d' {{filename}}
sed '/{{regex}}/,$!d' {{filename}}
- sed -i 修正をファイルに書き込む
 - sed '.../g' 末尾に g を追加すると全体操作が可能
 - sed '.../d' 末尾に d を追加すると削除操作
 - sed '/.../,/...' カンマは 2 つのパターンを一致させるために使用できる [段落を一致させる]
- 参考使用 sed で 2 つの一致パターンの間のすべての行を削除する?—— 腾讯云社区
 
 
【コマンドデモ】
① 上記の一般的なコマンドを順に操作

② 設定ファイルの特定の設定を置換するために使用
- 
 - 
削除 👉 追加
 - 
削除前にバックアップを作成
 - 
追加時に識別子 #newadd を追加し、後で sed 操作を容易にする
 - 
直接削除してから追加し、直接置換するのではなく、面倒なパターン一致を避ける [パラメータ値]
 
授業中の練習#
- 文字列中のすべての数字の合計を求める:"1 2 3 4 5 6 7 9 a v こんにちは . /8"
 - ファイル内のすべての大文字を小文字に変換する:echo "ABCefg" >> test.log
 PATH変数の最後のパスを見つけるlastコマンドを使用して、すべての再起動情報を出力する/etc/passwdの内容をユーザー名でソートする/etc/passwdの内容をuidでソートする- クラウドホストで最近 2 ヶ月のシステムログインユーザーの総人数を調べる
 - クラウドホストで最近 2 ヶ月にログインしたすべてのユーザー名を回数順にソートし、回数を出力する
 - ローカルの
/etcディレクトリ内のファイルとディレクトリ名を、10 行ごとに 1 つのファイルに保存する /etc/passwdに保存されている第 10 から 20 のユーザーを出力し、uid、gid、およびgroupsを表示する- ユーザー名に従って
/etc/passwdのユーザーを確認し、'sync'ユーザーに達したら終了し、そのユーザーのuid、gid、およびgroupsを出力する - 単語頻度の統計
 
① 以下のコマンドを使用してテキストファイル test.txt を生成する
cat >> test.txt << xxx
nihao hello hello こんにちは 
nihao
hello 
ls
cd
world
pwd
xxx
② a.txt 内の各単語の単語頻度を統計し、大から小の順に出力する。
答え
【1】
  [巧妙解法、需在bash下]
    echo "1 2 3 4 5 6 7 9 a v こんにちは . /8" | tr -s -c 0-9 "\n" | echo $[`tr "\n" "+"`0]
  [forループ]
    sum=0
    for i in `echo "1 2 3 4 5 6 7 9 a v こんにちは . /8" | tr -s -c 0-9 "\n"`; do
    for> sum=$[$sum+$i]
    for> done
  [awk解法1]
    echo "1 2 3 4 5 6 7 9 a v こんにちは . /8" | tr -s -c 0-9 "\n" | awk -v sum=0 '{sum += $1} END { print sum }'
  [awk解法2]
    echo "1 2 3 4 5 6 7 9 a v こんにちは . /8" | tr -s -c 0-9 " " | awk -v sum=0 '{for (i = 1; i <= NF; i++) {sum += $i} } END{print sum}'
【2】 cat test.log | tr A-Z a-z > test.log
【3】 echo ${PATH} | tr ":" "\n" | tail -1
【4】 last | grep "reboot"
【5】 cat /etc/passwd | sort
【6】 cat /etc/passwd | sort -t : -k 3 -n
【7】 last -f /var/log/wtmp.1 -f /var/log/wtmp | grep -v "^$" | grep -v "begins" | grep -v "reboot" | grep -v "shutdown" | wc -l
【8】 last -f /var/log/wtmp.1 -f /var/log/wtmp | grep -v "^$" | grep -v "begins" | grep -v "reboot" | grep -v "shutdown" | cut -d " " -f 1 | sort | uniq -c | sort -n -r
【9】 ls /etc | split -l 10
【10】 cat /etc/passwd | head -20 | tail -10 | cut -d : -f 1 | xargs -n 1 id
【11】 cat /etc/passwd | cut -d : -f 1 | xargs -e"sync" -n 1 id
【12】
  cat test.txt | tr -s " " "\n" | sort | uniq -c | sort -n -r
  [もし単語を前に、回数を後にしたい場合はawkで逆にする]
    cat test.txt | tr -s " " "\n" | sort | uniq -c | sort -n -r | awk '{print $2, $1}'
ヒント#
- 面接常考:単語頻度統計

- tr 置換👉ソート👉重複排除カウント👉ソート👉上位を表示