回答:
使用GNU sed
:
sed -i '$ d' foo.txt
この-i
オプションはGNU sed
3.95より前のバージョンには存在しないため、一時ファイルのフィルターとして使用する必要があります。
cp foo.txt foo.txt.tmp
sed '$ d' foo.txt.tmp > foo.txt
rm -f foo.txt.tmp
もちろん、その場合はのhead -n -1
代わりに使用することもできますsed
。
マックOS:
Mac OS X(10.7.4以降)では、sed -i
上記のコマンドと同等です。
sed -i '' -e '$ d' foo.txt
$ d
正規表現ではありません。sedコマンドです。d
行を削除するコマンドですが、$
「ファイルの最後の行」を意味します。コマンドの前に場所(sed lingoでは「範囲」と呼ばれます)を指定すると、そのコマンドは指定された場所にのみ適用されます。したがって、このコマンドは「ファイルの最終行の範囲で、それを削除する」と明示的に言っています。あなたが私に尋ねるなら、かなり滑らかでまっすぐなポイントです。
これは、特に大きなファイルの場合、断然最速かつ最も簡単なソリューションです。
head -n -1 foo.txt > temp.txt ; mv temp.txt foo.txt
あなたが一番上の行を削除したいなら、これを使ってください:
tail -n +2 foo.txt
これは、2行目から始まる出力行を意味します。
sed
ファイルの上部または下部から行を削除する場合は使用しないでください。ファイルが大きい場合は非常に遅くなります。
head -n -1 foo.txt
十分です
brew install coreutils
(GNUコアユーティリティ)を使用できます。ghead
head
FILE=$1; TAIL=$2; head -n -${TAIL} ${FILE} > temp ; mv temp ${FILE}
ます。cat TAILfixer ./TAILfixer myfile 4
次のようにmyfileからたとえば4行を削除するために実行します。もちろん、最初に実行可能にしますchmod +x TAILfixer
sed
、このコマンドもかなり遅いです
私はここですべての答えに問題がありました。なぜなら、私は巨大なファイル(〜300Gb)で作業していて、ソリューションのスケーリングが行われていないためです。これが私の解決策です:
dd if=/dev/null of=<filename> bs=1 seek=$(echo $(stat --format=%s <filename> ) - $( tail -n1 <filename> | wc -c) | bc )
つまり、最終的に必要なファイルの長さ(ファイルの長さから最後の行の長さを引いて、を使用bc
)を見つけ、その位置をファイルの最後に設定します(dd
1バイト /dev/null
をそれ)。
これは高速でtail
起動すると端から読み取り、dd
ファイルが上書きされます代わりにし、他のソリューションが何であるファイルのすべての行をコピー(および解析)するのではなく。
注:これにより、ファイルから行が削除されます!自分のファイルで試す前に、ダミーファイルでバックアップまたはテストしてください!
ファイルの最後の行を削除するには、ファイル全体を読んだり、何かを書き換えることなく、あなたが使用することができます
tail -n 1 "$file" | wc -c | xargs -I {} truncate "$file" -s -{}
最後の行を削除してstdoutに出力する(「ポップする」)には、次のコマンドを組み合わせますtee
。
tail -n 1 "$file" | tee >(wc -c | xargs -I {} truncate "$file" -s -{})
これらのコマンドは、非常に大きなファイルを効率的に処理できます。これはYossiの回答に似ており、それに触発されていますが、いくつかの追加機能の使用を回避しています。
これらを繰り返し使用してエラー処理やその他の機能が必要な場合は、httpspoptail
://github.com/donm/evenmoreutilsのコマンド
を使用できます。
truncate
OS Xではデフォルトでは使用できません。しかし、Brew:を使用してインストールするのは簡単ですbrew install truncate
。
Macユーザー
ファイル自体を変更せずに最後の行の出力のみを削除したい場合
sed -e '$ d' foo.txt
入力ファイル自体の最後の行を削除したい場合
sed -i '' -e '$ d' foo.txt
-i ''
は、パラメーターとして提供された拡張子を持つファイルにバックアップを保持しながら、ファイルをインプレースで変更するようにsedに指示します。パラメータは空の文字列であるため、バックアップファイルは作成されません。-e
コマンドを実行するようにsedに指示します。コマンドの$ d
意味:最後の行を見つけ($
)、それを削除します(d
)。
Macでは、head -n -1は機能しません。そして、「処理時間を気にすることなく」、「head」または「tail」コマンドのみを使用してこの問題を解決する簡単な解決策を見つけようとしていました。
私は次の一連のコマンドを試してみましたが、[Macで利用可能なオプションを使用して] "tail"コマンドを使用するだけでそれを解決できて嬉しかったです。したがって、Macを使用していて、「tail」のみを使用してこの問題を解決したい場合は、次のコマンドを使用できます。
cat file.txt | テール-r | 尾-n +2 | 尾-r
1> tail -r:入力の行の順序を逆にします
2> tail -n +2:入力の2行目から始まるすべての行を出力します
ghead -n -1
awk "NR != `wc -l < text.file`" text.file |> text.file
このスニペットはトリックを行います。
これらのソリューションはどちらも他の形式で提供されています。私はこれらがもう少し実用的で、明確で、有用であるとわかりました:
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}
sed '$d' ~/path/to/your/file/name
sed -i '' -e '$ d' ~/path/to/your/file/name
sed -i
上記のコマンドと同等ですsed -i '' -e '$ d' foo.txt
。また、head -n -1
現在Macでは動作しません。