web-dev-qa-db-ja.com

cutコマンドから最後から2番目のフィールドを取得する方法

入力としてデータのセットがあり、デリミターに基づいて最後から2番目のフィールドが必要です。行には異なる数の区切り文字が含まれる場合があります。最後から2番目のフィールドを取得するにはどうすればよいですか?

入力例

text,blah,blaah,foo
this,is,another,text,line

期待される出力

blaah
text
43
Archit Jain

最後の2つのトークンを除くUNIXカット からヒントを得て、答えを見つけ出すことができます:

cat datafile | rev | cut -d '/' -f 2 | rev
80
Archit Jain

Awkはこれに適しています。

awk -F, '{print $(NF-1)}' file

変数NFは、現在のレコードのフィールド数を含む特別なawk変数です。

40
Chris Seymour

cutrev、またはbashの外部にある他のツールを使用する必要はまったくありません。各行を配列に読み込んで、必要な部分を選択するだけです。

while IFS=, read -r -a entries; do
  printf '%s\n' "${entries[${#entries[@]} - 2]}"
done <file

これを純粋なbashで行うことは、少なくとも合理的に小さな入力の場合、パイプラインを起動するよりもはるかに高速です。大きな入力の場合、より良いツールはawkです。

6
Charles Duffy

@iiSeymourのawkソリューションに似たPerlソリューション

Perl -lane 'print $F[-2]' file

これらのコマンドラインオプションが使用されます。

  • n入力ファイルのすべての行をループし、すべての行を自動的に印刷しません

  • lは、処理する前に改行を削除し、後でそれらを追加します

  • a自動分割モード–入力行を@F配列に分割します。デフォルトは空白で分割します

  • e Perlコードを実行します

@F自動分割配列はインデックス[0]から始まり、awkフィールドは$ 1から始まります
-1は最後の要素です
-2は最後から2番目の要素です

3
Chris Koknat

GNU sed :のコード

 $ echo text、blah、blaah、foo | sed -r 's/^(\ S +、){2}(\ S +)、。*/\ 2 /'
 blaah 
 
 $ echo this、is、another、text、line | sed -r 's/^(\ S +、){2}(\ S +)、。*/\ 2 /'
テキスト

Sudo_Oのawkcode に類似したコード例:

 $ sed -r 's /.*、(\ w +)、\ w + $/\ 1 /' file 
 blaah 
 text 

CSVファイルには、より特殊なプログラムを使用することをお勧めします。 awk または Excel

2
captcha

この問題に対する最も最小限の答えは、私の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メッセージが出力されます。

2
arielf