ファイルパスと行番号から該当行抽出(sed in sed)

前回の最後に少しやりましたが、ファイルパスと行番号のリストから、該当する行を抽出してみます。

listは前回同様このようにファイル名と行番号が格納されています。

takk@deb9:~/tmp$ head list
x00:40
x00:72
x00:87
x01:25
x01:32
x01:36
x02:27
x02:60
x02:92
x04:17
takk@deb9:~/tmp$ 

各ファイル。

takk@deb9:~/tmp$ ls
x00  x01  x02  x03  x04  x05  x06  x07  x08  x09
takk@deb9:~/tmp$ 

まずは、bashの変数置換でファイル名と行番号をsedに指定して、行抽出する方法。

takk@deb9:~/tmp$ for i in `cat list`;do fn=${i%%:*};no=${i##*:};sed -ne ${no}p $fn;done
parrakeet
barraged
parrakeets
irritatingly
deterring
borrowed
irresistible
surrounds
harried
Barr's
guerrilla's
Lorraine's
irregularity's
surrealism's
Corrine
diarrhoea's
scarred
stirrer's
barren
Barrie's
takk@deb9:~/tmp$ 

長くて分かりづらい。なるべく使いたくない書き方です。

次も似たような感じですが、bashの配列を用いる方法。先ほどと同じ結果になります。

takk@deb9:~/tmp$ for i in `<list`;do a=(`tr : " " <<< $i`);sed -ne ${a[1]}p ${a[0]};done

これも分かりづらいし、括弧が多いのは間違いの元です。

もう少し簡潔にしたもの。

takk@deb9:~/tmp$ for i in `<list`;do sed -ne ${i##*:}p ${i%%:*};done

どうしてもbash変数使わなければならない時に、使うかもしれません。

次はsed in sed。sedの中でsedが登場します。覚えやすいし、私は一番使うかも。

takk@deb9:~/tmp$ sed -r 's/^(.*):(.*)$/sed -ne \2p \1/' list
sed -ne 40p x00
sed -ne 72p x00
sed -ne 87p x00
sed -ne 25p x01
sed -ne 32p x01
sed -ne 36p x01
sed -ne 27p x02
sed -ne 60p x02
sed -ne 92p x02
sed -ne 17p x04
sed -ne 11p x05
sed -ne 16p x05
sed -ne 23p x05
sed -ne 60p x05
sed -ne 87p x05
sed -ne 52p x06
sed -ne 14p x07
sed -ne 16p x09
sed -ne 57p x09
sed -ne 87p x09
takk@deb9:~/tmp$ 

sedでsedのリストを作った後は、それを実行すれば、該当行が抽出できます。

takk@deb9:~/tmp$ sed -r 's/^(.*):(.*)$/sed -ne \2p \1/' list | sh
parrakeet
barraged
parrakeets
irritatingly
deterring
borrowed
irresistible
surrounds
harried
Barr's
guerrilla's
Lorraine's
irregularity's
surrealism's
Corrine
diarrhoea's
scarred
stirrer's
barren
Barrie's
takk@deb9:~/tmp$ 

sedでできるなら、perlでもできますね。オプションで自動で配列@Fに格納されるので、スクリプトが短くできます。[]が好きであれば使うのですが、[]よりもやわらかい印象の()が好きなので、いまいち。

takk@deb9:~/tmp$ perl -F/:/ -pale '$_="sed -ne $F[1]p $F[0]"' list

最後は、awk。列分離はawkの得意技ですね。なんだかんだ一番分かりやすいかもしれません。

takk@deb9:~/tmp$ awk -F: '{printf "sed -ne %sp %s\n",$2,$1}' list

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA