次のファイル(somefile.txt)があります。
/A/1/B/1/C/1/D/1/E/1/F/2/G/1/H/1/I/1/J/1/K/1/
/B/1/C/1/D/1/E/1/F/5/G/1/H/1/I/1/J/1/K/1/
/C/1/D/1/E/1/F/9/G/1/H/1/I/1/J/1/K/1/
/D/1/E/1/F/7/G/1/H/1/I/1/J/1/K/1/
/A/1/B/1/C/1/D/1/E/1/F/8/G/1/H/1/I/1/J/1/K/1/
/A/1/B/1/C/1/D/1/E/1/F/3/G/1/H/1/I/1/J/1/K/1/
/A/1/B/1/C/1/D/1/E/1/F/6/G/1/H/1/I/1/J/1/K/1/
/B/1/C/1/D/1/E/1/F/8/G/1/H/1/I/1/J/1/K/1/
/D/1/E/1/F/3/G/1/H/1/I/1/J/1/K/1/
/C/1/D/1/E/1/F/6/G/1/H/1/I/1/J/1/K/1
私は次の結果が欲しい(後の次の数字F
):
2
5
9
7
8
3
6
8
3
6
1行あたりの列数が可変であれば、次のようにする方法はありますか? :
awk -F'/' '/F/ {print <column_of_match> + 1 }' somefile.txt
ベストアンサー1
Perlを使用すると配列の分割が便利なので、配列内の各要素のペアをハッシュのキーと値として扱うことができます。
$ perl -F/ -lane '%f = @F[1..$#F]; print $f{F}' input.txt
2
5
9
7
8
3
6
8
3
6
Perl-F
と-a
(自動分割)はawkと同様に機能しますが、行を自動的に$ 1、$ 2、$ 3などに分割するのではなく、各行をという配列に自動的に分割します@F
。
このスクリプトは、@F
配列スライス(0番目の要素を除くすべての要素)を名前付きハッシュ(連想配列)に変換し、%f
キー「F」を使用して要素を印刷します。%f
機能/動作方法(そして空の文字列である@ Fのゼロ番目の要素を除外する理由)を強調するために、使用時には次のようになり@F
ます%f
。データ::ダンプモジュールdump
機能:
$ perl -F/ -MData::Dump=dump -lane '
%f = @F[1..$#F];
print join("\n", $_, dump(@F), dump(\%f), $f{F}), "\n"' input.txt
/A/1/B/1/C/1/D/1/E/1/F/2/G/1/H/1/I/1/J/1/K/1/
("", "A", 1, "B", 1, "C", 1, "D", 1, "E", 1, "F", 2, "G", 1, "H", 1, "I", 1, "J", 1, "K", 1)
{ A => 1, B => 1, C => 1, D => 1, E => 1, F => 2, G => 1, H => 1, I => 1, J => 1, K => 1 }
2
/B/1/C/1/D/1/E/1/F/5/G/1/H/1/I/1/J/1/K/1/
("", "B", 1, "C", 1, "D", 1, "E", 1, "F", 5, "G", 1, "H", 1, "I", 1, "J", 1, "K", 1)
{ B => 1, C => 1, D => 1, E => 1, F => 5, G => 1, H => 1, I => 1, J => 1, K => 1 }
5
/C/1/D/1/E/1/F/9/G/1/H/1/I/1/J/1/K/1/
("", "C", 1, "D", 1, "E", 1, "F", 9, "G", 1, "H", 1, "I", 1, "J", 1, "K", 1)
{ C => 1, D => 1, E => 1, F => 9, G => 1, H => 1, I => 1, J => 1, K => 1 }
9
...and so on...
F
注:入力がない場合は空白行が印刷されます。これが望ましくない場合は、次のようにします。
perl -F/ -lane '%f = @F[1..$#F];
if (defined $f{F}) {
print $f{F}
} else {
print STDERR "Error on input line $.: F has absconded"
}' input.txt