コース内容#
データ抽出操作#
| コマンド | 機能 | コマンド | 機能 |
|:----:|:----|:----:|:----|:----:|:----|:----:|:----|
|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 置換👉ソート👉重複排除カウント👉ソート👉上位を表示