スペースを区切りコマンドとして区切りコマンドとして使用する


328

スペースを区切り文字として使用したい cutコマンドで。

これにはどの構文を使用できますか?


42
正しくない、カットのmanページはこれを説明しておらず、一般に情報を提供するものではありません
UncleZeiv

2
また、この場合、「情報カット」は改善されません。
カーディフスペースマン2013

3
@ mklement0思い出すと、削除されたコメントに返信していました。これには、この質問に対する回答がmanページで返されたため、正当な理由があるかどうかに関係なく、「正しくない」と私は考えていました。かどうか-今、私はこの情報不足の正当な理由があるかもしれないと認めていますが、一般的な使用例のないドキュメントは、まったく役に立たない場合でも、少なくとも苛立たせることが多いと思います
UncleZeiv

3
@UncleZeiv了解しました。明確にしていただきありがとうございます。この質問に関心があることを考えると、manページが十分ではないと考えるのは当然です。「タブ文字の代わりにフィールド区切り文字として-d delim使用する」を見てみましょうdelim。(BSD cutですが、GNUバージョンとPOSIX仕様はほとんど同じです)。シェルを使用して起動するcut-典型的なケース-したがって、シェル構文を使用して引数として一般的にスペースを渡す方法を知っている必要があります。これはおそらくcutmanページの仕事ではありません。ただし、実際の例は常に役立ちますが、GNUのマニュアルページにはありません。
mklement0

4
が、選択した答えは技術的に正確である、より多くの選択を検討最近の包括的な答えを、それがトップにフィルタリングするように標準的な答えとして、@ mklement0で。
David LeBauer、2015

回答:


367
cut -d ' ' -f 2

2は、スペースで区切られたフィールドのフィールド番号です。


2
RegExのように、特定の文字を区切り文字として使用するようにcutに指示できますか?たとえば、任意の数のスペース。たとえば、\ s +
両生類

3
@foampileいいえ、できるとは思いません。
Jonathan Hartley

6
で正規表現を使用することはできませんが、これを使用するとcutcutsすべてのcut制限を「修正」しようとすることができます:github.com/arielf/cuts
arielf

スペースで区切られたフィールドを3つおきに取得できますか?cut -d ' ' -f 3,6,9,12,15,18すべての番号を指定する必要がないように?
Monocito

169

通常、スペースを区切り文字として使用する場合は、いくつかの列をスペースに揃えてコマンドの出力を解析するため、複数のスペースを1つとして扱います。(そして、そのためのグーグル検索は私をここに導きます)

この場合、単一のcutコマンドでは不十分であり、以下を使用する必要があります。

tr -s ' ' | cut -d ' ' -f 2

または

awk '{print $2}'

2
awkの使用例に感謝します。
spazm 2016年

44

既存の役立つ回答を補足するため。別の回答を投稿するように私を励ましてくれたQZサポートへの帽子の先端:

ここでは、2つの異なるメカニズムが機能します。

  • ()かどうかcut 自体デリミタが必要(この場合はスペース)に渡す-dことがオプション別引数またはそれを追加するために許容されるのかどうかを直接-d

  • (b)シェルが通常、引数を、呼び出されるコマンドに渡す前に解析する方法。

(a)公益事業に関するPOSIXガイドラインからの引用によって回答されている(強調鉱山)

標準ユーティリティの概要が必須のオプション引数[...] を持つオプションを表示する場合、適合アプリケーションは、そのオプションとそのオプション引数に個別の引数を使用するものとしますただし、準拠する実装ではアプリケーションが、文字を介在させることなく、同じ引数文字列でオプションとオプション引数を指定すること許可するものとします

言い換えれば、この場合は、ので、-dオプション引数があるのは必須次のことができます選択したとして区切り文字を指定するかどうか

  • (s)EITHER:別の引数
  • (D)または:値と直接結合します-d

(s)または(d)を選択したら、それはシェルの文字列リテラル解析-(b)-重要です:

  • アプローチでは(s)は、以下のフォームの全ては等価です。

    • -d ' '
    • -d " "
    • -d \<space> # <space> used to represent an actual space for technical reasons
  • アプローチ(d)では、以下のすべての形式が同等です。

    • -d' '
    • -d" "
    • "-d "
    • '-d '
    • d\<space>

同等性は、シェルの文字列リテラル処理によって説明されます。

上記のcutすべてのソリューションは、それらを見るまでに(各グループで)まったく同じ文字列になります

  • (S) cut見て-dそのように、自分が続く引数、別の -引用符やなしにスペース文字が含まれている引数\の接頭辞!

  • (D) cut見ている-d プラス -引用符やなしにスペース文字を\接頭辞!- 同じ引数の一部として。

それぞれのグループのフォームが最終的に同一である理由はシェルが文字列リテラルを解析する方法に基づいて、2つあります

  • シェルを指定するリテラル可能であるようにを通じて呼び出さ機構引用取ることができ、いくつかの形式を
    • 一重引用符で囲まれた文字列:内部の内容'...'文字どおりに解釈され、単一の引数を形成します
    • 二重引用符で囲まれた文字列:内部の内容"..."単一の引数を形成しますが、補間さます$var、コマンド置換($(...)または`...`)などの変数参照、または算術展開($(( ... )))を展開します)。
    • \個々の文字の引用\単一の文字の前に置くと、その文字はリテラルとして解釈されます。
  • 引用は、によって補完された引用符除去シェルはコマンドラインを解析された後、それがあることを意味、削除された引数から引用文字を(囲む'...'か、"..."または\このように、 -インスタンス)が呼び出されているコマンドは、引用符を見たことがありません

36

次のように言うこともできます:

cut -d\  -f 2

バックスラッシュの後に2つのスペースがあることに注意してください。


30
「\」が次の文字をエスケープすることを知っている人は、次に何が起こるかを注意深く確認するでしょう。このようなスペース文字をエスケープするために「\」を使用することは、非常に一般的な慣用法です。
ジョナサンハートレー

3
@Jonathan Hartley一般に、ほとんどのコードは実際には読み取れ
ません

1
Linux / Unixの観点から\ は、私の最初の試みでしたが、うまくいきました。と比較すると' '、それほど明白ではないことに同意しますが、多くの人が行動の安心としてここを読んで喜んでいると思います。よりよく理解するために、以下の@ mklement0のコメントを参照してください。
tresf

@JonathanHartleyの修正:「'\'が次の文字をエスケープし、他の人もそれを知っていると想定する利己的な人」。個人的なプロジェクトではこれは当てはまりませんが、チーム設定では、その仮定は非常に危険な(そして潜在的にコストがかかる)ものです。
Eduard Nicodei 2017

1
@EduardNicodeiああ、同意します。私たちは、作者ではなく、コードの読者(「だれが気づくか...?」)しかし、一部のチームでは、ある程度の熟練度を想定しても問題ありません。環境によって異なります。
Jonathan Hartley

5

私はあなたが使うこともできることを発見しました"-d "

cut "-d "

テスト

$ cat a
hello how are you
I am fine
$ cut "-d " -f2 a
how
am

1
確かに-または'-d '
mklement0

3
ことを注意からcutの視点:次のすべてのが同一である"-d "'-d '-d" "-d' '、および-d\<space>すべてのフォームは、直接(オプションにオプション引数(スペース)を追加-d)との結果とまったく同じ文字列の時間でcutそれらを見ている:シングルシェル引用の削除
mklement0

1
@ mklement0の答えは 答え。このページで最も包括的なものです(コメントですが)。
tresf 2015年

@QZSupport:私は感情と励ましに感謝します-それは私に追加の背景情報を含む自分の答えを投稿するように促しました。
mklement0

1
笑魅力的な発見!
ハリー

4

たとえばデータに複数のスペースがある場合、カットを使用して簡単に行うことはできません。処理を簡単にするために入力を正規化すると便利です。1つのトリックは、以下のように正規化にsedを使用することです。

echo -e "foor\t \t bar" | sed 's:\s\+:\t:g' | cut -f2  #bar

3

切り傷は、perlの正規表現を破壊トークンとして使用できる、カットに似たユーティリティ(よりスマートですが、私が作成した方が遅い)です。空白で分割することがデフォルトですが、複数文字の正規表現、代替正規表現などで分割することもできます。

scut -f='6 2 8 7' < input.file  > output.file

したがって、上記のコマンドは空白で列を分割し、(0から始まる)cols 6 2 8 7をこの順序で抽出します。


0

sed正規表現とキャプチャグループを含む回答があります(やや紛らわしい回答を認めます)。

  • \S* -最初の単語
  • \s* -区切り文字
  • (\S*) -2番目の単語-キャプチャ
  • .* -残りの行

sed表現、キャプチャグループをエスケープする必要があり、すなわち\(\)

\1すなわち2番目の単語、キャプチャグループのコピーを返します。

$ echo "alpha beta gamma delta" | sed 's/\S*\s*\(\S*\).*/\1/'
beta

この答えを見ると、やや混乱しますが、なぜ気になるのでしょうか。まあ、私はいくつかが「あはっ」と行くことを望んでいます このパターンを使用して、1つのsed式で複雑なテキスト抽出の問題をいくつか解決します。

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