Bo2SS

Bo2SS

9 データ抽出、ソフトハード接続、線形ふるい、SED

コース内容#

データ抽出操作#

| コマンド | 機能 | コマンド | 機能 |
|:----:|:----|:----:|:----|:----:|:----|:----:|:----|
|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

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 つの 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}}

【コマンドデモ】

① 上記の一般的なコマンドを順に操作

画像

② 設定ファイルの特定の設定を置換するために使用

  • 画像
  • 削除 👉 追加

  • 削除前にバックアップを作成

  • 追加時に識別子 #newadd を追加し、後で sed 操作を容易にする

  • 直接削除してから追加し、直接置換するのではなく、面倒なパターン一致を避ける [パラメータ値]

授業中の練習#

  1. 文字列中のすべての数字の合計を求める:"1 2 3 4 5 6 7 9 a v こんにちは . /8"
  2. ファイル内のすべての大文字を小文字に変換する:echo "ABCefg" >> test.log
  3. PATH変数の最後のパスを見つける
  4. lastコマンドを使用して、すべての再起動情報を出力する
  5. /etc/passwdの内容をユーザー名でソートする
  6. /etc/passwdの内容をuidでソートする
  7. クラウドホストで最近 2 ヶ月のシステムログインユーザーの総人数を調べる
  8. クラウドホストで最近 2 ヶ月にログインしたすべてのユーザー名を回数順にソートし、回数を出力する
  9. ローカルの/etcディレクトリ内のファイルとディレクトリ名を、10 行ごとに 1 つのファイルに保存する
  10. /etc/passwdに保存されている第 10 から 20 のユーザーを出力し、uidgid、およびgroupsを表示する
  11. ユーザー名に従って/etc/passwdのユーザーを確認し、'sync'ユーザーに達したら終了し、そのユーザーのuidgid、およびgroupsを出力する
  12. 単語頻度の統計

① 以下のコマンドを使用してテキストファイル 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 置換👉ソート👉重複排除カウント👉ソート👉上位を表示

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。