サーチ…


前書き

cutコマンドは、テキストファイルの行の一部を高速に抽出する方法です。それは最も古いUnixコマンドに属します。その最も普及した実装は、Linux上に見られるGNU版とMacOS上に見出されるFreeBSD版ですが、Unixのそれぞれの特色は独自のものです。違いについては以下を参照してください。入力行は、 stdinから、またはコマンド行で引数としてリストされたファイルから読み込まれます。

構文

  • cut -f1,3#最初 3番目のタブ区切り フィールドを抽出する(stdinから)

  • cut -f1-3#最初から 3番目のフィールドから抽出する (両端を含む)

  • カット-f-3#-3は1-3と解釈されます

  • cut -f2-#2-は2番目から最後まで解釈されます

  • cut -c1-5,10#stdinから1,2,3,4,5,10の位置にある文字を抽出します。

  • cut -s -f1#区切り文字を含まない行を抑制する

  • cut --complement -f3#(GNUカットのみ)3番目のフィールドを除く すべてのフィールド抽出する

パラメーター

パラメータ詳細
-f、--fields フィールドベースの選択
-d、--delimiter フィールドベースの選択の区切り文字
-c、--characters 文字ベースの選択、区切り文字無視またはエラー
-s、--only-delimited デリミタ文字を含まない行を表示しない(そうでない場合は印刷される)
- 補体反転された選択(指定されたフィールド/文字を除くすべて抽出
- 出力デリミタ入力区切り文字と異なる必要があるときを指定する

備考

1.構文の違い

上記の表の長いオプションは、GNUバージョンでのみサポートされています。

2.キャラクターは特別な扱いを受けない

FreeBSD cut (例えばMacOSに付属)には--complementスイッチがありません。文字範囲の場合は、代わりにcolrmコマンドを使うことができます:

  $ cut --complement -c3-5 <<<"123456789"
  126789

  $ colrm 3 5 <<<"123456789"
  126789

しかし、大きな違いがあります。なぜなら、 colrmはTAB文字(ASCII 9)を実際の表colrmとして8の次の倍数に、バックスペース(ASCII 8)を-1として扱うからです。逆に、 cutはすべての文字を1列幅として扱います。

  $ colrm  3 8 <<<$'12\tABCDEF' # Input string has an embedded TAB
  12ABCDEF

  $ cut --complement -c3-8 <<<$'12\tABCDEF'
  12F

3.(まだまだ)国際化

cutが設計されたとき、すべての文字は1バイト長であり、国際化は問題ではありませんでした。より広範な文字を持つシステムを書くことが一般的になったとき、POSIXが採用した解決策は、バイト数が何バイトであろうと、文字の選択という意味を保持すべき古い-cスイッチと、新しいスイッチ-bを導入することです。現在の文字エンコーディングに関係なく、 バイトを選択します 。最も一般的な実装では、 -bが導入され、動作しますが、 -c-bとまったく同じように動作します。たとえば、GNU cut

SEの迷惑メールフィルタは、孤立した漢字で英語のテキストをブラックリストに載せているようだ。私はこの制限を克服することができなかったので、以下の例はあまり表現力がありません。

  # In an encoding where each character in the input string is three bytes wide,
  # Selecting bytes 1-6 yields the first two characters (correct)
  $ LC_ALL=ja_JP.UTF-8 cut -b1-6 kanji.utf-8.txt
  ...first two characters of each line...
  

  # Selecting all three characters with the -c switch doesn’t work.
  # It behaves like -b, contrary to documentation.
  $ LC_ALL=ja_JP.UTF-8 cut -c1-3 kanji.utf-8.txt
  ...first character of each line...

  # In this case, an illegal UTF-8 string is produced.
  # The -n switch would prevent this, if implemented.
  $ LC_ALL=ja_JP.UTF-8 cut -n -c2 kanji.utf-8.txt
  ...second byte, which is an illegal UTF-8 sequence...

文字がASCII範囲外で、 cutを使用する場合は、エンコーディングの文字幅を常に認識し、それに応じて-bを使用する必要があります。文書化されているように-cが動作し始めると、スクリプトを変更する必要はありません。

4.速度の比較

cutの限界は人々にその有用性を疑わせる。実際、より強力でより一般的なユーティリティによって同じ機能を実現することができます。しかし、 cutの利点はその性能です。いくつかの速度の比較については下記を参照してください。 test.txtは300万行があり、空白で区切られた5つのフィールドがそれぞれあります。 awkテストでは、 mawkが使われました。なぜなら、それはGNU awkより速いからです。シェル自体(最後の行)ははるかに最悪のパフォーマーです。与えられたtime (秒)は、 timeコマンドがリアルタイムで与えるものです。

(誤解を避けるために、テストされたすべてのコマンドは、与えられた入力で同じ出力を出しましたが、もちろん同等ではなく、さまざまな状況で異なる出力を与えます。特に、フィールドが可変スペースで区切られている場合)

コマンド時間
cut -d ' ' -f1,2 test.txt 1.138秒
awk '{print $1 $2}' test.txt 1.688秒
join -a1 -o1.1,1.2 test.txt /dev/null 1.767秒
perl -lane 'print "@F[1,2]"' test.txt 11.390秒
grep -o '^\([^ ]*\) \([^ ]*\)' test.txt 22.925秒
sed -e 's/^\([^ ]*\) \([^ ]*\).*$/\1 \2/' test.txt 52.122秒
while read ab _; do echo $a $b; done <test.txt 55.582秒

5.参照マニュアルページ

基本的な使用法

一般的な使用法は、各行が区切り文字で区切られたフィールドで構成され、 -dオプションで指定されたCSV形式のファイルです。デフォルトの区切り文字はTAB文字です。 data.txtような行を持つデータファイルがあるとします

0 0 755 1482941948.8024
102 33 4755 1240562224.3205
1003 1 644 1219943831.2367

その後、

# extract the third space-delimited field
$ cut -d ' ' -f3 data.txt
755
4755
644

# extract the second dot-delimited field
$ cut -d. -f2 data.txt    
8024
3205
2367

# extract the character range from the 20th through the 25th character
$ cut -c20-25 data.txt 
948.80
056222    
943831

いつものように、スイッチとそのパラメータの間にはオプションのスペースがあります: -d, -d ,と同じですが-d ,

GNU cut--output-delimiterオプションを指定することができます(この例の独立した特徴は、シェルによる特殊な処理を避けるために入力区切り文字としてのセミコロンをエスケープする必要があるということです)

$ cut --output-delimiter=, -d\; -f1,2 <<<"a;b;c;d"
a,b

1つの区切り文字

-d ",;:"ようなものを指定した場合、デリミタ(この場合はカンマ)として最初の文字のみが使用されます。他の実装(GNU cut )では、エラーメッセージが表示されます。

$ cut -d ",;:" -f2 <<<"J.Smith,1 Main Road,cell:1234567890;land:4081234567"
cut: the delimiter must be a single character
Try `cut --help' for more information.

繰り返されるデリミタは空のフィールドとして解釈されます

$ cut -d, -f1,3 <<<"a,,b,c,d,e"
a,b

スペースで区切られた文字列では、いくつかの文字列にはあまり明らかではないかもしれません

$ cut -d ' ' -f1,3 <<<"a  b c d e"
a b

shellや他のプログラムのように引数を解析するためにcutを使うことはできません。

引用なし

区切り文字を保護する方法はありません。スプレッドシートや同様のCSV処理ソフトウェアは通常、区切り文字を含む文字列を定義できるテキスト引用文字を認識できます。 cutはできません。

$ cut -d, -f3 <<<'John,Smith,"1, Main Street"'
"1

抽出する、操作しない

行の一部だけを抽出し、フィールドの順序を変更したり繰り返すことはできません。

$ cut -d, -f2,1 <<<'John,Smith,USA' ## Just like -f1,2
John,Smith
$ cut -d, -f2,2 <<<'John,Smith,USA' ## Just like -f2
Smith


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow