web-dev-qa-db-ja.com

'cut'コマンドで同じ連続区切り文字を1つとして扱う方法は?

列ベースの「スペース」調整済みテキストストリームから特定の(4番目の)フィールドを抽出しようとしています。 cutコマンドを次のように使用します。

cat text.txt | cut -d " " -f 4

残念ながら、cutは複数のスペースを1つの区切り文字として扱いません。私はawkを介してパイプを通すことができた

awk '{ printf $4; }'

またはsed

sed -E "s/[[:space:]]+/ /g"

スペースを折りたたむために、私はcutといくつかの区切り文字をネイティブに扱う方法があるかどうか知りたいですか?

294
mbaitoff

試してください:

tr -s ' ' <text.txt | cut -d ' ' -f4

trのマニュアルページから:

  -  s、 -  squeeze-repeatsは、SET1にリストされている繰り返し文字
の各入力シーケンスを、その文字
が1回出現する
に置き換えます。
525
kev

あなたがあなたの質問にコメントするように、awkは本当に進むべき道です。 kev's answer が示すように、cuttr -sと一緒に使用してスペースを絞り込むことができます。

しかし私は将来の読者のためにすべての可能な組み合わせを見てみましょう。説明はテストセクションにあります。

tr |カット

tr -s ' ' < file | cut -d' ' -f4

awk

awk '{print $4}' file

bash

while read -r _ _ _ myfield _
do
   echo "forth field: $myfield"
done < file

sed

sed -r 's/^([^ ]*[ ]*){3}([^ ]*).*/\2/' file

テスト

このファイルを考えて、コマンドをテストしましょう。

$ cat a
this   is    line     1 more text
this      is line    2     more text
this    is line 3     more text
this is   line 4            more    text

tr |カット

$ cut -d' ' -f4 a
is
                        # it does not show what we want!


$ tr -s ' ' < a | cut -d' ' -f4
1
2                       # this makes it!
3
4
$

awk

$ awk '{print $4}' a
1
2
3
4

bash

これはフィールドを順番に読み込みます。 _を使用することによって、これがこれらのフィールドを無視するための「ジャンク変数」としての使い捨て変数であることを示します。このようにして、$myfieldをファイル内の4番目のフィールドとして、それらの間のスペースに関係なく格納します。

$ while read -r _ _ _ a _; do echo "4th field: $a"; done < a
4th field: 1
4th field: 2
4th field: 3
4th field: 4

sed

これは3つのグループのスペースをキャッチし、([^ ]*[ ]*){3}でスペースを取りません。それから、4番目のフィールドとしてスペースまで来るものは何でもキャッチします。それは最終的に\1で印刷されます。

$ sed -r 's/^([^ ]*[ ]*){3}([^ ]*).*/\2/' a
1
2
3
4
86
fedorqui

最短/最善の解決策

cutの制限が多すぎてイライラするようになった後、私は自分自身の代わりのものを書きました。これを「ステロイドのカット」のために cuts と書きました。

cuts は、これおよび他の多くのに関連するカット/ペーストの問題に対する最も簡単な解決策と思われるものを提供します。

多くのうち、この特定の質問に対処するための1つの例

$ cat text.txt
0   1        2 3
0 1          2   3 4

$ cuts 2 text.txt
2
2

cuts は以下をサポートします。

  • ファイル内の最も一般的なフィールド区切り文字の自動検出(+デフォルトをオーバーライドする機能)
  • 複数文字、混合文字、および正規表現の一致した区切り文字
  • 混合区切り文字を使用して複数のファイルから列を抽出する
  • 行頭に加えて行末からのオフセット(負数を使用)
  • 列を自動的に並べて貼り付ける(pasteを個別に呼び出す必要はありません)
  • フィールド並べ替えのサポート
  • ユーザーが自分の個人的な好みを変更できる設定ファイル
  • ユーザーの親しみやすさと必要最低限​​のタイピングを重視

そしてもっとたくさん。どちらも標準のcutでは提供されていません。

こちらもご覧ください: https://stackoverflow.com/a/24543231/1296044

ソースとドキュメンテーション(フリーソフトウェア): http://arielf.github.io/cuts/

24
arielf

このPerlのワンライナーは、Perlがawkとどれほど密接に関連しているかを示しています。

Perl -lane 'print $F[3]' text.txt

ただし、@F自動分割配列はインデックス$F[0]で始まり、awkフィールドは$1で始まります。

3
Chris Koknat

私が知っているcutのバージョンでは、いいえ、これは不可能です。 cutは、区切り文字が空白ではなく(/etc/passwdなど)、フィールド数が固定されているファイルの解析に主に役立ちます。行内の2つの区切り記号は空のフィールドを意味し、それは空白にも当てはまります。

2
Benoit