- PR -

bash ファイルの特定の行へジャンプ

投稿者投稿内容
Johann
ベテラン
会議室デビュー日: 2005/08/31
投稿数: 52
投稿日時: 2005-10-11 13:46
お世話になっております。

bashのシェルスクリプトで、あるテキストファイル(a.txt)の特定の行Nのみを
表示させる方法を探しています。

現在では、head -N a.txt | tail -1

という風に処理しているのですが、もっと効率良い方法は無いでしょうか。
ご存知の方いらっしゃいましたらご教授お願い致します。

[ メッセージ編集済み 編集者: Johann 編集日時 2005-10-11 13:52 ]
angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2005-10-11 14:11
こんにちは。
私も、基本的に同じ方法 ( head/tail -n 行数 ) を使用していますね…。

一応、コマンドを短くする意味でしたら、

 $ sed -e 'N!d' ファイル名

というのもアリでしょうか…。

 例:5行目を抜き出してみる
  $ seq 20 | sed -e '5!d'
  5

良い、かどうかは分かりませんが。
以上、ご参考まで。
Johann
ベテラン
会議室デビュー日: 2005/08/31
投稿数: 52
投稿日時: 2005-10-11 14:19
angelさん、早速のご返事ありがとうございます。

sed -e 'N!d'、試したところちゃんと目的の行だけ表示されました。
早速パフォーマンスを測ってみます。
(かなり膨大なデータのバッチ処理をやっていまして、head/tailコンボがボトルネックになっているのかな?と踏んでいたのです)

どうもありがとうございました。

[ メッセージ編集済み 編集者: Johann 編集日時 2005-10-11 14:20 ]
MMX
ぬし
会議室デビュー日: 2001/10/26
投稿数: 861
投稿日時: 2005-10-11 15:02
いまどき sed のmanを読むのも 「フォ〜」(小学生まね)ですが
読み込みの打ち切りもできる、ようです

sed -n -e "5{p;Q}" input.txt

Q Immediately quit the sed script without processing
any more input.

[ メッセージ編集済み 編集者: MMX 編集日時 2005-10-11 15:36 ]
angel
ぬし
会議室デビュー日: 2005/03/17
投稿数: 711
投稿日時: 2005-10-11 15:26
引用:
いまどき sed のmanを読むのも 「フォ〜」(小学生)ですが
読み込みの打ち切りもできる、ようです


おお、そちらの方が良いですね。
恐らく私の方法だと、巨大ファイルの先頭部分を抽出したい時に、膨大な無駄が発生するでしょうから。

実験くん:
 $ wc -c 巨大ファイル
 13082009 巨大ファイル

 $ wc -l 巨大ファイル
 262155 巨大ファイル

 $ time sh -c 'i=0; while [ $i -lt 100 ]; do head -n 10000 巨大ファイル | tail -n 1 >/dev/null; i=$(expr $i + 1); done'

 real 0m1.67s
 user 0m0.60s
 sys 0m1.04s

 $ time sh -c 'i=0; while [ $i -lt 100 ]; do sed -ne "10000p;10001q" 巨大ファイル >/dev/null; i=$(expr $i + 1); done'

 real 0m1.31s
 user 0m0.48s
 sys 0m0.79s

 $ time sh -c 'i=0; while [ $i -lt 100 ]; do sed -e "10000!d" 巨大ファイル >/dev/null; i=$(expr $i + 1); done'

 real 0m22.70s
 user 0m11.95s
 sys 0m6.93s

なんともはや。

訂正:一部 -lt を -le と写し間違えましたので、訂正しました。

[ メッセージ編集済み 編集者: angel 編集日時 2005-10-11 15:30 ]
コブラ
ぬし
会議室デビュー日: 2003/07/18
投稿数: 1038
お住まい・勤務地: 神奈川
投稿日時: 2005-10-11 16:08
レーザーラモン出ました。

#!/bin/sh

awk '{ if(NR == '$1'){ print $0; exit; } }' a.TXT

[ メッセージ編集済み 編集者: コブラ 編集日時 2005-10-11 16:09 ]
Johann
ベテラン
会議室デビュー日: 2005/08/31
投稿数: 52
投稿日時: 2005-10-12 14:51
angelさん、MMXさん、コブラさんお返事ありがとうございます。

先ほどシミュレーションしてみたところ、
head -N a.txt | tail -1コンボでは1時間50分、sed -ne "N{p;Q}" a.txtでは2時間ちょっとかかりました。

head|tailコンボが速かったのが意外でした。ボトルネックでは無かったみたいですね。。

いずれにしても、sedの使い方はよく理解していないので大変参考になりました。
どうもありがとうございました。
今川 美保(夏椰)
ぬし
会議室デビュー日: 2004/06/10
投稿数: 363
お住まい・勤務地: 神奈川県茅ヶ崎市
投稿日時: 2005-10-12 15:19
自分が昔やった手段を思い出しました。

cat buf.list | nl -s":" | grep "10:"

これをファイルサイズの大きいもので試したかどうかは
思い出せないのですが、
参考になればと思いまして。

スキルアップ/キャリアアップ(JOB@IT)