Unixのコマンドcutの範囲

Unixのコマンドcutの範囲

シェル スクリプトを作成しようとしています。次のように、'cut' UNIX コマンドを使用して文字列を切り取ります。

namecmpaux=$(echo $namecmp |cut -c0-19)

しかし、シェルを実行すると次のエラーが表示されます。

cut: fields and positions are numbered from 1 
Try `cut - help 'for more information.

以前は 'cut' コマンドで下限位置を 0 に設定していたのを覚えていますが、今はコマンドは 1 から開始する必要があると表示されます。なぜでしょうか。オペレーティング システムによって異なります。以前は SunOS を使用していましたが、現在は ubuntu 12.04 を使用しています。

答え1

いいえ、どの実装でも同じですcut。数字は 1 から始まりますが、Solaris のものは 0 を指定してもエラーを起こさず、1 として扱います。 と0はどちらも1最初の文字を意味し、2は 2 番目の文字を意味します。

$ echo test | cut -c 0-2
te
$ echo test | cut -c 1-2
te

busybox cutまたはcut組み込み関数ksh93も文句を言いません。GNU はcut、最初のインデックスが何であるかについて正しい考えを持っていない可能性が高いことを知らせることで、ユーザーを支援しようとしているだけです。

ただし、実際の違いは、GNU と busybox cut(少なくとも 2014-03-27 時点では) は をバイト単位でカウントするのに対し-c、Solaris または ksh はcut(POSIX の要件に従って) 文字単位でカウントすることです。

$ echo 'Stéphane' | cut -c 1-4
Sté
$ echo 'Stéphane' | busybox cut -c 1-4
Sté
$ echo 'Stéphane' | ksh -c 'command /opt/ast/bin/cut -c 1-4'
Stép

(UTF-8ロケールでは、é(U+00E9)は2バイトを占めます)

答え2

はい、それは確かに OS に依存する可能性があります (または、 のバージョンを作成した人に依存しますcut)。

を見れば、 GNU の が1 からバイト、文字、フィールドをカウントしているman cutことがわかります。cutcoreutils

-b、-c、-f のいずれか 1 つだけを使用します。[...] 各範囲は次のいずれかです。
      いいえ      いいえ1から数えて、'番目のバイト、文字、またはフィールド

繰り返しになりますが、メンテナーが GNU 以外の実装を使用することを決定した場合、これは別のシステムでは異なる可能性があります。cutそのため、安全のために、man ページを確認して確認してください。

答え3

以前は Linux でも動作していました。Debian で cut コマンドを含む coreutils パッケージを更新した後、このバグに遭遇しました。

これは coreutils のバグです:

バグ:

誰かが故意に下位互換性を破壊し、誰もそれを修正しませんでした。以前は 0 も問題なく 1 として扱われていました。しかし、現在は 0 はエラーを生成します。そのため、この動作に依存するすべてのスクリプトは壊れており、変更する必要があります。

関連情報