■ はじめに
なんだかんだで、シェルスクリプト(Bsh)を扱う機会があって その中で文字列抽出をちょこちょこのだが、すぐに忘れてしまう、、、 で、ブログにまとめておいたつもりだったが、 全然まとまっていなかったので、今回で整理する。 また、cut / revコマンドを学んだので、ついでにメモっておく。
目次
【0】実行環境 【1】cut / rev コマンドで抽出する 例1:Pythonバージョンを短く抽出する 例2:ファイル名から特定の文字列を抽出する 例3:【Key】:【Value】の文字列抽出 & Trim 例4:Docker image名からImage名/Tag名を抽出する 例5:JDBC URLからHost/Portを抽出する 【2】sedコマンドで抽出する 【3】awkコマンドで抽出する 例1:カンマ区切りの文字列を抽出する 【4】bashによる文字列置換 【5】grepコマンドで抽出する 【6】WhiteSpaceでパースする
【0】実行環境
* 気軽に動作確認するなら、以下のサイトが便利。
https://paiza.io/projects/QzTJKlZTT6VvvqVUGNvT4A?language=bash
【1】cut / rev コマンドで抽出する
* 文字列が固定されている場合に有効。
a) cutコマンド
* 文字列を切り出す
オプション | 説明 | サンプル |
---|---|---|
-c <数字> | 切り出す位置の指定する | 例1参照 |
-d <区切り文字> | 区切り文字の指定(d:delimiter)。-fを組み合わせる | 例2参照 |
-f <区切り文字> | 項目数の指定(f:fields)。-dを組み合わせる | 例2参照 |
https://eng-entrance.com/linux-command-cut
b) revコマンド
* 文字列を逆順にする(e.g. "World" => "dlroW")
例1:Pythonバージョンを短く抽出する
PYTHON_VERSION="3.10.13" # 3.10.13 -> 3.10 PYTHON_SHORT_VERSION=`echo $PYTHON_VERSION | cut -d '.' -f 1,2` # PYTHON_SHORT_VERSION=3.10 echo "PYTHON_SHORT_VERSION=$PYTHON_SHORT_VERSION"
例2:ファイル名から特定の文字列を抽出する
# ファイル名。ここから「sample_table」を抽出する input_data="0000_sample_table_xxxx.sql" echo "0) input_data = ${input_data}" data1=`echo ${input_data} | cut -c 6-` echo "1) data1 = ${data1}" data2=`echo ${data1} | rev | cut -c 10- | rev` echo "2) data2 = ${data2}"
出力結果
0) input_data = 0000_sample_table_xxxx.sql 1) data1 = sample_table_xxxx.sql 2) data2 = sample_table
例3:【Key】:【Value】の文字列抽出 & Trim
#!/bin/bash result=" Total Size: 102400" key=`echo ${result} | cut -d ':' -f 1 | sed 's/^ *\| *$//'` # key=Total Size echo "key=${key}" value=`echo ${result} | cut -d ':' -f 2 | sed 's/^ *\| *$//'` # value=102400 echo "value=${value}"
例4:Docker image名からImage名/Tag名を抽出する
source="xxxx.xxx.ecr.us-west-2.amazonaws.com/hello-world-ecr:latest" image_name=`echo ${source} | cut -d ':' -f 1` tag_name=`echo ${source} | cut -d ':' -f 2` echo "image_name=${image_name}" echo "tag_name=${tag_name}"
出力結果
image_name=xxxx.xxx.ecr.us-west-2.amazonaws.com/hello-world-ecr tag_name=latest
例5:JDBC URLからHost/Portを抽出する
jdbc_url="jdbc:postgresql://localhost:5432/sample_db" host_n_port=`echo ${jdbc_url} | cut -d '/' -f 3` host=`echo ${host_n_port} | cut -d ':' -f 1` port=`echo ${host_n_port} | cut -d ':' -f 2` echo "host_n_port=${host_n_port}" echo "host=${host}" echo "port=${port}"
出力結果
host_n_port=localhost:5432 host=localhost port=5432
参考文献
https://shuzo-kino.hateblo.jp/entry/2015/04/12/153737
【2】sedコマンドで抽出する
* sed (セド) は、文字列の置換/削除するコマンド => 不要な部分を削除してしまえば、抽出することができる * 詳細は、以下の関連記事を参照のこと。
sedコマンド
https://dk521123.hatenablog.com/entry/2019/11/23/101625
例1:ファイル名からデータの一部を抽出する
https://www.atmarkit.co.jp/ait/articles/1610/18/news008.html
# 「(~)」により、文字列の一部を取り出せる echo "systemname_table1.sql" | sed -r 's/systemname_(.*).sql$/\1/'
出力結果
table1
例2:取り出した値を変数に格納する
https://myokoym.hatenadiary.org/entry/20110408/1302292907
#!/bin/bash # 'person'を取りたい。100は可変。 result=`echo "100_table_name_person.sql" | sed -r "s/^.*_table_name_(.*).sql$/\1/"` echo "Result : ${result}"
出力結果
Result : person
【3】awkコマンドで抽出する
* awk (オーク) は、区切り文字のテキストを処理するコマンド * 詳細は、以下の関連記事を参照のこと。
https://dk521123.hatenablog.com/entry/2019/11/22/223043
1)サンプル
例1:カンマ区切りの文字列を抽出する
# [構文] awk -F'[区切り文字]' 'パターン {アクション}' result=`echo "1,2,4,8" | awk -F',' '{print $3}'` # Result is 4 ($3 で3番目の要素を出力した) echo "Result is ${result}"
例2:ドット区切りの文字列を抽出し、くっつけ直す
# [構文] awk -F'[区切り文字]' 'パターン {アクション}' result=`echo "3.10.14" | awk -F'.' '{ printf("%s.%s", $1, $2) }'` # Result is 3.10 ($1, $2 で1,2番目の要素を出力した) echo "Result is ${result}"
【4】bashによる文字列置換
* 詳細は、以下の関連記事を参照のこと。
https://dk521123.hatenablog.com/entry/2020/03/24/223323
【5】grepコマンドで抽出する
以下を参考にした。
https://ez-net.jp/article/7A/9qV1-XpJ/6o8QiIwz08um/
1)サンプル
hiveコマンド「DESC FORMATTED <your_table_name>;」で 得られた結果をファイルに保存して、その結果をパースする
https://dk521123.hatenablog.com/entry/2023/02/21/223137
sample.sh
#!/bin/bash echo "Start!" location=`grep -i "Location:" input.txt | sed -e "s/^\([^:]*\):\(.*\)$/\2/" | sed 's/^ *\| *$//'` location=${location:--} last_access_time=`grep -i "LastAccessTime:" input.txt | sed -e "s/^\([^:]*\):\(.*\)$/\2/" | sed 's/^ *\| *$//'` last_access_time=${last_access_time:--} table_type=`grep -i "Table Type:" input.txt | sed -e "s/^\([^:]*\):\(.*\)$/\2/" | sed 's/^ *\| *$//'` table_type=${table_type:--} num_rows=`grep -i "numRows" input.txt | xargs echo | cut -d ' ' -f 2 | sed 's/^ *\| *$//'` num_rows=${num_rows:--} total_size=`grep -i "totalSize" input.txt | xargs echo | cut -d ' ' -f 2 | sed 's/^ *\| *$//'` total_size=${total_size:--} num_partitions=`grep -i "numPartitions" input.txt | xargs echo | cut -d ' ' -f 2 | sed 's/^ *\| *$//'` num_partitions=${num_partitions:--} # location = hdfs://user/hive/wrehouse/default/book echo "===location = ${location}===" # last_access_time = UNKNOWN echo "===last_access_time = ${last_access_time}===" # table_type = MANAGED_TABLE echo "===table_type = ${table_type}===" # num_rows = 11 echo "===num_rows = ${num_rows}===" # total_size = 20 echo "===total_size = ${total_size}===" # num_partitions = - echo "===num_partitions = ${num_partitions}===" echo "DONE..."
input.txt
# col_name data_type comment id string name string year int pages int # Detailed Table Information Database: default Owner: hadoop CreateTime: Thu Mar 21 09:28:45 PDT 2019 LastAccessTime: UNKNOWN Protect Mode: None Retention: 0 Location: hdfs://user/hive/wrehouse/default/book Table Type: MANAGED_TABLE Table Parameters: COLUMN_STATS_ACCURATE {\"BASIC_STATS\":\"true\"} numFiles 0 numRows 11 rawDataSize 0 totalSize 20 transient_lastDdlTime 1553185725 # Storage Information SerDe Library: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe InputFormat: org.apache.hadoop.mapred.TextInputFormat OutputFormat: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat Compressed: No Num Buckets: -1 Bucket Columns: [] Sort Columns: [] Storage Desc Params: serialization.format 1
【6】WhiteSpaceでパースする
* 以下に載っているやり方が一番やりやすい
サンプル
sentence="This is a Hello world!!" sentence_array=($sentence) echo ${sentence_array[0]} for value in "${sentence_array[@]}" do echo $value done
参考文献
https://myokoym.hatenadiary.org/entry/20110408/1302292907
関連記事
シェル ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2014/10/23/005406
シェル ~ 文字列置換 ~
https://dk521123.hatenablog.com/entry/2023/10/25/000000
JDBC を シェルスクリプトでパースする
https://dk521123.hatenablog.com/entry/2020/03/24/223323
シェルで split するには
https://dk521123.hatenablog.com/entry/2021/09/02/000000
sedコマンド
https://dk521123.hatenablog.com/entry/2019/11/23/101625
awkコマンド
https://dk521123.hatenablog.com/entry/2019/11/22/223043