入力としてデータのセットがあり、デリミターに基づいて最後から2番目のフィールドが必要です。行には異なる数の区切り文字が含まれる場合があります。最後から2番目のフィールドを取得するにはどうすればよいですか?
入力例
text,blah,blaah,foo
this,is,another,text,line
期待される出力
blaah
text
最後の2つのトークンを除くUNIXカット からヒントを得て、答えを見つけ出すことができます:
cat datafile | rev | cut -d '/' -f 2 | rev
Awkはこれに適しています。
awk -F, '{print $(NF-1)}' file
変数NFは、現在のレコードのフィールド数を含む特別なawk変数です。
cut
、rev
、またはbashの外部にある他のツールを使用する必要はまったくありません。各行を配列に読み込んで、必要な部分を選択するだけです。
while IFS=, read -r -a entries; do
printf '%s\n' "${entries[${#entries[@]} - 2]}"
done <file
これを純粋なbashで行うことは、少なくとも合理的に小さな入力の場合、パイプラインを起動するよりもはるかに高速です。大きな入力の場合、より良いツールはawkです。
@iiSeymourのawkソリューションに似たPerlソリューション
Perl -lane 'print $F[-2]' file
これらのコマンドラインオプションが使用されます。
n
入力ファイルのすべての行をループし、すべての行を自動的に印刷しません
l
は、処理する前に改行を削除し、後でそれらを追加します
a
自動分割モード–入力行を@F配列に分割します。デフォルトは空白で分割します
e
Perlコードを実行します
@F
自動分割配列はインデックス[0]から始まり、awkフィールドは$ 1から始まります-1
は最後の要素です-2
は最後から2番目の要素です
cuts
ユーティリティを使用することです:$ cat file.txt
text,blah,blaah,foo
this,is,another,text,line
$ cuts -2 file.txt
blaah
text
cuts、「ステロイドのカット」の略:
- automatically figures out the input field separators
- supports multi-char (and regexp) separators
- automatically pastes (side-by-side) multiple columns from multiple files
- supports negative offsets (from end of line)
- has good defaults to save typing + allows the user to override them
などなど。
Unix上のcuts
の制限が多すぎてイライラした後、cut
を書きました。さまざまなcut
/paste
コンボ、複数のファイルからの列のスライスとダイシングを複数の区切り文字のバリエーションで置き換えながら、ユーザーによる最小限のタイピングを課すように設計されています。
Githubからcuts
(フリーソフトウェア、Artistic Licence)を取得できます。 https://github.com/arielf/cuts/
引数なしでcuts
を呼び出すと、詳細なUsage
メッセージが出力されます。