次の行を含むファイルfoo.txt
があります。
a
b
c
foo.txt
の内容が次のようになるような単純なコマンドが必要です。
a
b
GNU sed
を使う:
sed -i '$ d' foo.txt
-i
オプションは3.95より前のGNU sed
バージョンには存在しないので、あなたはそれを一時ファイルのフィルタとして使う必要があります:
cp foo.txt foo.txt.tmp
sed '$ d' foo.txt.tmp > foo.txt
rm -f foo.txt.tmp
もちろん、その場合はsed
の代わりにhead -n -1
を使うこともできます。
MacOS:
Mac OS X(10.7.4以降)では、上記のsed -i
コマンドと同じです。
sed -i '' -e '$ d' foo.txt
これは、特に大きなファイルでは、はるかに高速で簡単な解決策です。
head -n -1 foo.txt > temp.txt ; mv temp.txt foo.txt
一番上の行を削除したい場合は、これを使用してください。
tail -n +2 foo.txt
これは2行目から始まる出力行を意味します。
ファイルの上または下から行を削除するためにsed
を使用しないでください - ファイルが大きい場合は非常に遅くなります。
私はここですべての答えに問題がありました。なぜなら私はHUGEファイル(〜300Gb)を使って作業していて、どのソリューションも拡張できなかったためです。これが私の解決策です:
dd if=/dev/null of=<filename> bs=1 seek=$(echo $(stat --format=%s <filename> ) - $( tail -n1 <filename> | wc -c) | bc )
つまり、(bc
を使用して、ファイルの長さからその最後の行の長さの長さを引いたもの)で終わらせたいファイルの長さを調べ、その位置をファイルの終わりに設定します。 1バイトの/dev/null
をdd
ingします。
tail
は最後から読み込みを開始し、dd
はファイルの各行をコピー(および解析)するのではなく、ファイルを上書きするため、これは高速です。それが他の解決策がすることです。
注:これにより、ファイルから行が削除されます。自分のファイルで試してみる前に、ダミーファイルのバックアップまたはテストを行ってください!
ファイル全体を読んだり何かを書き換えたりせずにファイルから最後の行を削除するには、次のようにします。
tail -n 1 "$file" | wc -c | xargs -I {} truncate "$file" -s -{}
最後の行を削除してそれを標準出力に( "ポップ")出力するには、そのコマンドをtee
と組み合わせることができます。
tail -n 1 "$file" | tee >(wc -c | xargs -I {} truncate "$file" -s -{})
これらのコマンドは非常に大きなファイルを効率的に処理できます。これはYossiの答えに似ていて、それに触発されていますが、それはいくつかの余分な関数を使うことを避けます。
これらを繰り返し使用し、エラー処理やその他の機能が必要な場合は、ここでpoptail
コマンドを使用できます。 https://github.com/donm/evenmoreutils
Macユーザー
ファイル自体を変更せずに最後の行だけを削除したい場合
sed -e '$ d' foo.txt
入力ファイルの最後の行自体を削除したい場合
sed -i '' -e '$ d' foo.txt
Macでは、head -n -1は機能しません。そして、私は(処理時間を心配せずに) "head"や "tail"コマンドだけを使ってこの問題を解決する簡単な解決策を見つけようとしていました。
私は以下の一連のコマンドを試してみましたが、[tail]コマンドを[Macで利用可能なオプションで]使用するだけで解決できたことを嬉しく思います。あなたがMacを使用していて、この問題を解決するために "tail"だけを使いたいのであれば、このコマンドを使うことができます。
猫file.txt | tail -r | tail -n + 2 | tail -r
1> tail -r:単に入力の行の順番を逆にする
2> tail -n + 2:入力の2行目から始まるすべての行を印刷します。
echo -e '$d\nw\nq'| ed foo.txt
awk 'NR>1{print buf}{buf = $0}'
基本的に、このコードは次のように言っています。
最初の行以降の各行について、バッファ行を印刷します。
各行について、バッファをリセットする
バッファは1行遅れているので、1行目からn-1行目を印刷することになります。
awk "NR != `wc -l < text.file`" text.file |> text.file
このスニペットはトリックを行います。
これを手動で行う方法は次のとおりです(ファイルの最後の行をすばやく削除する必要がある場合、私は個人的にこの方法をよく使用します)。
vim + [FILE]
そこにある+
記号は、ファイルがvimテキストエディターで開かれたときに、カーソルがファイルの最終行に配置されることを意味します。
キーボードでd
を2回押すだけです。これはまさにあなたが望むことをします-最後の行を削除します。その後、:
に続いてx
を押し、次にEnter
を押します。これにより、変更が保存され、シェルに戻ります。これで、最後の行が正常に削除されました。
これらの解決策はどちらも他の形式です。私はこれらがもう少し実用的、明確、そして有用であることを見出しました:
Ddを使う:
BADLINESCOUNT=1
ORIGINALFILE=/tmp/whatever
dd if=${ORIGINALFILE} of=${ORIGINALFILE}.tmp status=none bs=1 count=$(printf "$(stat --format=%s ${ORIGINALFILE}) - $(tail -n${BADLINESCOUNT} ${ORIGINALFILE} | wc -c)\n" | bc )
/bin/mv -f ${ORIGINALFILE}.tmp ${ORIGINALFILE}
切り捨ての使用
BADLINESCOUNT=1
ORIGINALFILE=/tmp/whatever
truncate -s $(printf "$(stat --format=%s ${ORIGINALFILE}) - $(tail -n${BADLINESCOUNT} ${ORIGINALFILE} | wc -c)\n" | bc ) ${ORIGINALFILE}