デモ

デモ

OSXでは、次のコマンドを使用してファイルの行数を計算します。

nl=$(wc -l < ~/myfile.txt)

たとえば、結果は100です。今、私は結果を別のコマンドに使用したいのですが、nl奇妙なことにnl

echo 1-$nl

1- 100代わりに私にください1-100

デモ

cv me$ nl=$(wc -l < ~/Desktop/cap.xlsx)
cv me$ echo $nl
104
cv me$ echo 1-$nl
1- 104

ここに画像の説明を入力してください。

ここに画像の説明を入力してください。

なぜこれが起こるのですか?どうやって入手できますか1-100

答え1

POSIXで定義されているように、出力にはwc次の形式の各入力ファイルのエントリを含める必要があります。

"%d %d %d %s\n", <newlines>, <words>, <bytes>, <file>

ただし、出力ファイル形式のpseudo printf()-stringはSystem Vのバージョンとは異なりますwc

"%7d%7d%7d %s\n"

POSIXは先行スペースを追加する必要がないため、必要に応じて自由に実行できます。wc少なくともOSXおよびwcHeirloom Toolboxには、出力に先行スペースを追加するさまざまな実装があります。

$ /usr/5bin/wc -l /tmp/file
      3  /tmp/file

GNU wcは、オプションなしで標準入力から読み取るときに先行スペースを追加します。

$ cat file | wc
  5       5      65

POSIX シェルから先行スペースをすべて削除するには、次の手順を実行します。

set -f
set -- $nl
nl=$1
set +f

このメソッドは、変数に先行または末尾の空白のみが含まれ、中間スペースは含まれていないと仮定します。ab

答え2

wc実装時に先行スペースを作成できます。これはオプションが使用されているかどうか(および数)によって異なります(wcたとえば、GNUはあなたの場合のように1つのオプションのみが使用されている場合はスペースを生成しません)。これらのスペースは作業中に保持されますnl=$(...)。スペースを削除するには、回避策として次のいずれかの方法を使用できます。

nl=$(wc -l < ~/myfile.txt | awk '{print $1}')

または

nl=$(awk 'END{print NR}' ~/myfile.txt)

または

nl=$(wc -l < ~/Desktop/cap.xlsx)
nl=$(echo $nl)

または(しかし、以下の@cuonglmの説明を参照してください。家族家宝バージョンwc

nl=$(wc -l < ~/Desktop/cap.xlsx)
nl=${nl##* }

答え3

最も簡単なソリューション(bashまたは他のPOSIXシェル):

nl=$(wc -l < ~/myfile.txt)
nl=$(($nl))

$((...))算術拡張標準に使用されるため、sh結果は常に数値自体です。出力が生成されない場合wc -l(ファイルが読み取れない場合など)、0代わりに空の文字列が生成されます。

$((nl))でも動作できますが、bashPOSIXは数値定数を含まず、$nl実際には動作しないため、これを保証しません。yash

以下を使用して、これらすべてを一度に実行することもできます。

nl=$(($(wc -l < ~/myfile.txt)))

これの利点は、終了状態が保存されることですwc

答え4

先行スペースと末尾のスペースを削除する簡単な修正方法は、スペースを整数に変換することです。

echo 1-$nl

到着

echo 1-$(($nl))

関連情報