2-5 データの~行目から~行目までを切り出す。


 ファイルのp行目からq行目まで抽出したい場合、さまざまなコマンドでそれができます。sed、head、tail等もありますが、この目的に関して一番汎用性が高くかつ書きやすいコマンドはawkだと思うので、まずそれを紹介します。sed、head、tail等を使った方法は下記におまけとして紹介します。

#!/bin/sh 
cat data1.txt | awk "NR==8,NR==29 {print}" > result.txt
もしくは
#!/bin/sh 
cat data1.txt | awk 'NR==8,NR==29 {print}' > result.txt
と書くと、8行目から29行目まで抽出したデータがresult,txtに出力されます。awkはファイルを抽出したり処理したりする非常に便利なコマンドで、awkコマンドだけで1冊の本が書けるくらいに様々なことができます。ここでは行の抽出をまず紹介します。NRは「何行目」を示す情報です。はじめのNR==8が開始行、NR==29が終了行を意味します。最後の{print}の部分は「そのままprintする」という命令です、つまり「8行目から29行目まで取り出して、そいつをそのままprintしろ」というコマンドです。実はそのままprintするだけでなく、データを加工・演算したりして出力させることもできますが、ここではそこまでは触れないことにします。

 上記の2つのシェルスクリプトは同じ動きをします。しかし、以下のように開始行と終了行を変数に入れた場合、ダブルクオテーションでなくてはなりません。

#!/bin/sh 
p=8 q=29 cat data1.txt | awk "NR==$p,NR==$q {print}" > result.txt
シングルクオテーションにするとエラーがでます。これはダブルクオテーションで囲まれたものは$pや$qを展開してpを8、qを29と読み込む一方、シングルクオテーションで囲まれた部分は展開されずに「$p」という文字列として認識されてしまうからです。クオテーションには非常に注意してください。

 最初の行から43行目まで抽出する時は、もっと簡単に書くこともできます

#!/bin/sh 
cat data1.txt | awk 'NR<=43 {print}' > result.txt
10行目以降をすべて抽出したい場合も
#!/bin/sh 
cat data1.txt | awk 'NR>=10 {print}' > result.txt
で大丈夫です。ちなみに等号なしの不等号でもコマンドは書けます。
#!/bin/sh 
cat data1.txt | awk 'NR>10 {print}' > result.txt
(これだと11行目以降が抽出されますが)。このように、非常にわかりやすいコマンドでファイルの行の抽出ができるので、個人的にはawkコマンドが一番好きです。もちろん後述のようにほかのコマンドでも代用できますが、少しわかりにくい構文になるのであまりおすすめはしません。

    ★おまけ~ほかのコマンドによる行の抽出~

①sedコマンド

#!/bin/sh 
sed -n "13, 27p" data1.txt > result.txt
sedコマンドは本来置換をする目的で使うコマンドです。ただ汎用性が高く、「~行目から~行目まで取り出す」という用途にも使えます。 -nとpのペアは「条件に該当する行のみをすべて表示する」という意味です。そして「13,27」というのがその条件で、「13行目から27行目」という条件を意味しています。ちなみに「13行目から後ろすべて」を出力したい場合、
#!/bin/sh 
sed -n "13, $p" data1.txt > result.txt
とすればよいです。sedコマンドは様々な用途に使えるので、また以後たびたび出てきます。

②headコマンド、tailコマンド
「ファイルの初めの~行」、や「ファイルの最後の~行」を取り出したい場合、headコマンドやtailコマンドで抽出ができます。例えば data.txtファイルの初めの3行を取り出したファイルresult.txtを作成したいとします。その場合headコマンド(ファイルの頭を表示するコマンド)を使って

#!/bin/sh 
head -3 data1.txt > result.txt
とすれば、はじめの3行が取り出されます。また逆に
#!/bin/sh 
tail -3 data1.txt > result.txt
とやれば、最後の3行が取り出されます。これらのコマンドは書くのが簡単ですが、「初めの~行」「最後の~行」という目的にしか使えません。もちろん、headとtailを組み合わせば「~行目から~行目までを抽出する」ことは可能ですが、awkコマンドで書いた方がsmartで楽だと個人的には思います。
前項目へ  次項目へ  目次へ戻る

E-mail : endo cat.phys.s.u-tokyo.ac.jp