コース内容#
データ抽出操作#
| コマンド | 機能 | コマンド | 機能 |
|:----:|:----|:----:|:----|:----:|:----|:----:|:----|
|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 毎回受け取る引数の数を指定⭐、一度にすべてを渡すのではなく
- 引数を 1 つしか受け取れないコマンド [例: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、ブロック、スーパーブロック
- inode:ファイルノード
- 1 つの inode は 1 つのファイルに対応
- ファイル情報 [ファイル権限、所有者、時間...] とファイルの実際の位置 [ブロック位置] を保存
- ブロック位置を保存できない場合は、多重ブロックを使用
- ブロック:ファイルの実際の保存位置、1 つのブロックは一般的に 4096 バイト
- スーパーブロック:少なくとも 2 つ、ファイルシステム全体の情報を保存 [例:inode、ブロック...]
【ハードリンク】は別名に相当
- 元のファイルと同じ inode を持つ
- ファイルの接続数 > 1
- [PS]
- 別名を削除しても元のファイルには影響しない
- 現在のディレクトリと親ディレクトリはハードリンクである [特殊なディレクトリ]
- ただし、ハードリンクはディレクトリをサポートせず、無限ループなどの問題が発生する可能性がある。参考:
- なぜ UNIX/Linux ではディレクトリへのハードリンクが許可されていないのか?——StackExchange
- なぜディレクトリにハードリンクが許可されていないのか?——StackExchange
- linux ではなぜディレクトリをハードリンクできないのか?—— 知乎
【ソフトリンク】はショートカットに相当
- 新しいファイルを作成し、自分の inode を持ち、ブロックを指す [ファイルの実際の位置を保存]
- ファイルタイプは 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 つのマッチパターンの間のすべての行を削除するには?——Tencent Cloud Community
【コマンドデモ】
① 上記の一般的なコマンドを順に操作
② 設定ファイルの特定の設定を置換するために使用
-
-
削除 👉 追加
-
削除前にバックアップを作成
-
追加時に識別子 #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 置換👉ソート👉重複カウント👉ソート👉上位を表示