'cut'コマンドで同じシーケンシャルデリミタを1つとして扱う方法は?


309

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

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

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

awk '{ printf $4; }'

またはsed

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

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


12
AWKは進むべき道です。
追って通知があるまで一時停止。

回答:


546

試してください:

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

trmanページから:

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

24
catここは必要ありません。に< text.txt直接渡すことができtrます。en.wikipedia.org/wiki/Cat_%28Unix%29#Useless_use_of_cat
arielf 14

1
それがもっと簡単かどうかはわかりませんが、マージするつもりなら、カットを忘れ-dて複数の文字からタブに直接変換できます。例:ディスプレイを自動的にエクスポートする方法を探してここに来ました:who am i | tr -s ' ()' '\t' | cut -f5
Leo

これは、awkソリューションとは対照的に、先頭または末尾の空白(不要か不要であるが、通常は不要)を削除しません。また、awkソリューションは、はるかに読みやすく、冗長ではありません。
n.caillou 2018

-1 警告:これは、連続デリミタを1つとして処理するのと同じものではありません。比較echo "a b c" | cut -d " " -f2-echo "a b c" | tr -s " " | cut -d " " -f2-
user541686

96

あなたが質問にコメントするとき、それawkは本当に行く方法です。kevの答えが示すように、スペースを圧搾するcutことと一緒に使用することが可能です。tr -s

ただし、将来の読者のために考えられるすべての組み合わせについて説明します。説明はテストセクションにあります。

tr | 切る

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

awk

awk '{print $4}' file

バッシュ

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

バッシュ

これにより、フィールドが順番に読み込まれます。を使用_することにより、これはこれらのフィールドを無視する「ジャンク変数」としての使い捨て変数であることを示します。このようにして、$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

2
awkエレガントでシンプルなだけでなく、VMware ESXiにも含まれており、tr欠落しています。
user121391

2
@ user121391使用するもう1つの理由awk
fedorqui 'SO stop harming'

@fedorquiアンダースコアを「ジャンク変数」と聞いたことはありません。これについてさらに洞察/参照を提供できますか?
BryKKan 2017年

1
@BryKKan Greg's How it I read a file(data stream、variable)read a line-by-line(and / or field-by-field)?一部の人々は、スローアウェイ変数_を「ジャンク変数」として使用してフィールドを無視します。それ(または実際に任意の変数)は、単一の中で複数回使用することもできますread何が必要かを気にしない場合はコマンドます。それは何もすることができ、それが何らかの形ではなく、標準になったということだけですjunk_varwhatever:)
「SOストップ傷つける」fedorqui

25

最短/最も簡単なソリューション

の制限が多すぎることに不満を感じた後cut、私は自分自身の代わりのものを書きました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/


4

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

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

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


3

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.