質問
cut
コマンドで区切り文字としてスペースを使用したい。
これに使用できる構文は何ですか?
解決
cut -d ' ' -f 2
2は、スペースで区切られたフィールドのフィールド番号です。
他のヒント
通常、スペースを区切り文字として使用する場合、複数のスペースを1つとして扱います。これは、一部の列をスペースで整列するコマンドの出力を解析するためです。 (そして、そのためのグーグル検索がここに私を導きます)
この場合、単一のcut
コマンドでは不十分であり、次を使用する必要があります。
tr -s ' ' | cut -d ' ' -f 2
または
awk '{print $2}'
既存の有用な回答を補完するため。別の回答を投稿することを奨励してくれた QZサポートへのヒント:
2つの異なるメカニズムがここで登場します:
-
(a)
cut
それ自体が separate argument である-d
オプションに渡される区切り文字(この場合はスペース)を必要とするかどうかまたは-d ' '
に直接を追加してもよいかどうか。 -
(b) shell が一般に引数を解析してから、呼び出されるコマンドに渡す方法。
(a)にはユーティリティのPOSIXガイドライン(強調鉱山)
標準ユーティリティの概要に、オプションの引数が必須のオプションが表示されている場合[...]適合アプリケーションは、そのために別個の引数を使用する必要がありますオプションとそのオプション引数。 ただし、準拠する実装では、アプリケーションが文字を介在させずに同じ引数文字列でオプションとオプション引数を指定することを 許可する必要があります。
>
言い換えると、この場合、 -d " "
のオプション引数は必須 であるため、 選択できます区切り文字を次のように指定するかどうか:
- (s)いずれか: 別個の引数
- (d)または:値として 直接接続して
-d \<space> # <space> used to represent an actual space for technical reasons
に。
(s)または(d)を選択すると、それは shell の文字列リテラル解析です-(b)-重要なのは:
-
アプローチ(s)では、次のすべてのフォームが同等です:
-
-d' '
-
-d" "
-
"-d "
-
-
アプローチ(d)では、次のすべてのフォームが同等です:
-
'-d '
-
d\<space>
-
\
-
'...'
-
"..."
-
等価性は、 shell の文字列リテラル処理によって説明されます。
上記のすべてのソリューションは、$var
それらが表示されるまでに(各グループで)まったく同じ文字列になります:
-
(s):
$(...)
は、 own 引数として`...`
を参照し、その後に separate 引数が続くスペース文字を含む-引用符または$(( ... ))
プレフィックスなし!。 -
(d):<=>は<=> plus スペース文字を表示します-引用符や<=>プレフィックスなし! -同じ引数の一部として。
各グループのフォームが最終的に同一である理由は、 シェルが文字列リテラル を解析する方法に基づいて2つあります:
>- シェルでは、引用 と呼ばれるメカニズムにより、リテラルを現状のまま指定できます。これは、いくつかの形式 >:
- 一重引用符で囲まれた文字列:<=>内のコンテンツはリテラルになり、単一引数を形成します
- 二重引用符で囲まれた文字列:<=>内の内容も単一引数を形成しますが、補間(変数参照を展開します) <=>、コマンド置換(<=>または<=>)、算術展開(<=>)など。
- <=>-個々の文字の引用:単一の文字の前に<=>があると、その文字はリテラルとして解釈されます。
- 引用は、 引用の削除 によって補完されます。つまり、シェルがコマンドラインを解析すると、引数から引用文字を 削除する(<=>または<=>または<=>インスタンスを囲む)-したがって、 呼び出されるコマンドには引用文字は表示されません。
また言うことができます
cut -d\ -f 2
バックスラッシュの後に2つのスペースがあることに注意してください。
I ちょうど発見もできます"-d "
:
cut "-d "
テスト
$ cat a
hello how are you
I am fine
$ cut "-d " -f2 a
how
am
scut 、カットのようなユーティリティ(よりスマートだが遅いI作成)perl正規表現を破壊トークンとして使用できます。空白で区切ることがデフォルトですが、マルチ文字正規表現、代替正規表現などで区切ることもできます。
scut -f='6 2 8 7' < input.file > output.file
そのため、上記のコマンドは空白の列を分割し、(0から始まる)列6 2 8 7をその順序で抽出します。
たとえば、データに複数のスペースがある場合、cutで簡単に実行することはできません。処理を簡単にするために入力を正規化すると便利だと感じました。 1つの秘isは、以下のようにsedを使用して正規化することです。
echo -e "foor\t \t bar" | sed 's:\s\+:\t:g' | cut -f2 #bar
sed
、正規表現、およびキャプチャグループを含む回答があります(やや紛らわしい回答を認めます):
-
\S*
-最初の単語 -
\s*
-区切り文字 -
(\S*)
-2番目の単語-キャプチャ -
.*
-行の残り
\(
式として、キャプチャグループ、つまり\)
および\1
をエスケープする必要があります。
<=>は、キャプチャされたグループのコピー、つまり2番目の単語を返します。
$ echo "alpha beta gamma delta" | sed 's/\S*\s*\(\S*\).*/\1/'
beta
この答えを見ると、やや紛らわしいですが、なぜあなたは気にするのでしょうか?まあ、私はいくつかの人が<!> quot; Aha!<!> quot;このパターンを使用して、単一の<=>式でいくつかの複雑なテキスト抽出の問題を解決します。