59

head標準入力の最後の行を除くすべてをユーティリティに表示させようとしています。私が必要とした実際のコードは、cat myfile.txt | head -n $(($(wc -l)-1)). しかし、それはうまくいきませんでした。私はこれを Darwin/OS X で行っていますが、これにはhead -n -1同様の出力が得られるような優れたセマンティクスがありません。

これらのバリエーションはどれも機能しません。

cat myfile.txt | head -n $(wc -l | sed -E -e 's/\s//g')
echo "hello" | head -n $(wc -l | sed -E -e 's/\s//g')

より多くのバリエーションをテストしたところ、特にこれが機能することがわかりました。

cat <<EOF | echo $(($(wc -l)-1))
>Hola
>Raul
>Como Esta
>Bueno?
>EOF
3

これも機能する簡単なものです。

echo "hello world" | echo $(($(wc -w)+10))

これにより、当然のことながら、不正な行数エラーが発生します。しかし、少なくともhead、サブシェル/コマンド置換に何かを渡す前に、プログラムが標準入力を消費していないことがわかります。これはリモートの可能性ですが、とにかく除外したかったのです。

echo "hello" | head -n $(cat && echo 1)

ここでサブシェルを介した と の動作とそれらの相互作用をhead説明するものは何ですか? wcご協力いただきありがとうございます。

4

6 に答える 6

90

head -n -1入力の最後の行を除くすべてを提供します。

于 2013-08-08T13:47:43.177 に答える
75

headは間違ったツールです。最後の行以外をすべて表示したい場合は、次を使用します。

sed \$d

その理由は

# Sample of incorrect code:
echo "hello" | head -n $(wc -l | sed -E -e 's/\s//g')

失敗するとwc、すべての入力が消費され、何も表示されなくheadなります。 wcの出力から読み取っている、それが実行されているサブシェルから stdin を継承しますecho。入力を消費すると、戻っheadてデータを読み込もうとしますが、すべて消えてしまいます。入力を 2 回読み取りたい場合は、データをどこかに保存する必要があります。

于 2013-08-08T13:49:28.080 に答える
13

sed を使用:

sed '$d' filename

ファイルの最後の行を削除します。

$ seq 1 10 | sed '$d' 
1
2
3
4
5
6
7
8
9
于 2013-08-08T13:56:35.797 に答える
10

特に Mac OS X の場合、この Q&A へのコメントから回答を見つけました。

Homebrew を使用していると仮定して、次のコマンドを実行してbrew install coreutils使用します。ghead

cat myfile.txt | ghead -n -1

または、同等に:

ghead -n -1 myfile.txt

最後に、コマンドをプレフィックスなしで (たとえば、 の代わりに)brew info coreutils使用するかどうかを確認します。gheadghead

于 2016-06-13T13:52:46.837 に答える
6
cat myfile.txt | echo $(($(wc -l)-1))

これは機能します。echo $(($(wc -l)-1)) <myfile.txt非常に複雑です: orと書くだけですecho $(($(wc -l <myfile.txt)-1))。問題はあなたの使い方です。

cat myfile.txt | head -n $(wc -l | sed -E -e 's/\s//g')

wc行をカウントしているため、すべての入力が消費されます。そのため、開始するまでにパイプで読み取るデータは残っていませんhead

wc入力がファイルからのものである場合、そのファイルから と の両方をリダイレクトできheadます。

head -n $(($(wc -l <myfile.txt) - 1)) <myfile.txt

データがパイプから取得される可能性がある場合は、それを複製する必要があります。ストリームを複製する通常のツールは ですが、ここでは からの 2 つの出力が同じレートで生成されるteeため、それだけでは十分ではありません。一方、ここでは、開始する前にその出力を完全に消費する必要があります。代わりに、最後の行を検出できる単一のツールを使用する必要があります。これはとにかくより効率的なアプローチです。teewchead

便利なことに、sed は最後の行を照合する方法を提供します。最後の行を除くすべての行を印刷するか、最後の出力行を抑制するかのいずれかが機能します。

sed -n '$! p'
sed '$ d'
于 2013-08-08T14:15:22.997 に答える
0
awk 'NR>1{print p}{p=$0}'

このジョブでは、awk ワンライナーは sed ワンライナーよりも少し長くなります。

于 2013-08-08T13:56:42.120 に答える