Closed4

Linuxコマンド | パイプライン

うぱうぱ

パイプライン

$ls -a | grep 'txt'のようにパイプライン|を使って複数のコマンドを組み合わせて実行できる。

|以降の記述がオプションのように感じられていたが、実際にはパイプラインがコマンドの標準出力を次のコマンドの標準入力に渡しているのである。

catlesstacなどの表示コマンドをパイプラインの後ろに入力することで、パイプラインの前の部分が出力した文字列などを入力として受け取って表示してくれる。
tacは逆から表示する。文字通り、catの逆である。)

うぱうぱ

cut コマンド

cutによって入力の一部を取り出すことができる。
cut -d , -f 2 lucasNumber.csv

-d はdelimiter のことで区切り文字を指定できる。デフォルトはtab。
-f は field を表し、指定したフィールド番号の文字列のみを出力する。

$ cat LucasNumber.csv
1,2
1,1
2,3
3,4
5,7
8,11
13,18
21,29
34,47
55,76
89,123
144,199
233,322
$ cut -d , -f 2 LucasNumber.csv
2
1
3
4
7
11
18
29
47
76
123
199
322
うぱうぱ

awkコマンド

開発者3名の頭文字がコマンド名の由来。

1行ずつ入力を読み取っていき、区切り文字によって入力行を区切り、プログラミング言語のように処理を行うことができる。
awk [-F <区切り文字>] '<処理>' <file名>
ファイル名を指定しない場合には標準入力から読み込むので、フィルタとして使用することもできる。

区切られた値は各行左から順に$1, $2, ...で表される。($0は行全体)
例えば、フィボナッチ数、リュカ数の第4項は次のように表示できる。

$ awk -F , 'NR==4{fibo4=$1;lucas4=$2} END{print fibo4, lucas4}' LucasNumber.csv
3 4

フィボナッチ数とリュカ数の以下の性質を n=3, m=7 の場合で確認してみる。

2F_{n+m}=F_{n}L_{m+1}+F_{m}L_{n+1}

ここで、フィボナッチ数は以下とし、

F_{1}=1, F_{2}=1, F_{n+2}:=F_{n+1}+F_{n}

リュカ数は以下とする。
L_{1}=1, L_{2}=1, L_{n+2}:=L_{n+1}+L_{n}

$ awk -F , 'NR==3{fibo3=$1} NR==4{lucas4=$2} NR==7 {fibo7=$1} NR==8{lucas8=$2} NR==10 {fibo10=$1}END {print 2*fibo10, fibo3*lucas8, fibo7*lucas4}' LucasNumber.csv
110 58 52

NRは読み込んでいる行の行番号(Number of Records)


複雑な処理をする場合、コマンドがとても長くなってしまいそうだが、-fオプションでawkスクリプトを読み込んで処理を行うこともできる。

FiboLucas.awk
NR==3{fibo3=$1} NR==4{lucas4=$2} NR==7 {fibo7=$1} NR==8{lucas8=$2} NR==10 {fibo10=$1}END {print 2*fibo10, fibo3*lucas8, fibo7*lucas4}
$ awk -F , -f FiboLucas.awk LucasNumber.csv
110 58 52

for文やif文なども使用可能なので、様々なパターンで計算することができる。

うぱうぱ

awkコマンド その2

フィボナッチ数とリュカ数の以下の性質を確認するawkスクリプトを作成してみる。

\tag{1}2L_{n+m+1}=L_{n+1}L_{m+1}+5F_{n}F_{m}

Lucas5Fibo.awk
BEGIN {N=10;  i=1;}
{
fibo[NR]=$1;
lucas[NR]=$2;
}
END{
sum = 2*lucas[N+1];
print sum;
while(i<N){
LL= lucas[N-i+1]*lucas[i+1];
FF = 5 * fibo[N-i]*fibo[i];
print LL, FF, LL+FF;
i++;
}}

BEGIN{}はファイルを読み込む前に実行されるコードブロックで、END{}はファイルを読み込んだ後に実行されるコードブロックである。
BEGIN{}内でN:=n+mやイテレータiの初期値を設定した後に、フィボナッチ数、リュカ数を配列に格納し、ENDwhile内で(1)の右辺を計算している。

awkでは変数と同様に配列も宣言する必要はなく、fibo[NR]=$1;のようにいきなり書いてしまえる。

awkスクリプトを使って処理を実行すると以下のような結果が得られる。

$ awk -F , -f Lucas5Fibo.awk LucasNumber.csv
246
76 170 246
141 105 246
116 130 246
126 120 246
121 125 246
126 120 246
116 130 246
141 105 246
76 170 246

ファイル加工に大変便利なコマンド。

このスクラップは2023/12/16にクローズされました