web-dev-qa-db-ja.com

ファイルの最後の改行文字を削除する

すべての改行を削除するには、次のように言います:

tr -d '\n' < days.txt
cat days.txt | tr -d '\n'

しかし、trを使用して、テキストファイルの最後/下にある改行だけを削除するにはどうすればよいでしょうか。

最後の1つだけを指定するかどうかはわかりません。

22
user1257724

A)改行文字がファイルの最後にあり、b)文字が1バイトの大きさであるという事実を利用してください:truncateコマンドを使用して、ファイルを1バイト縮小します。

# a file with the Word "test" in it, with a newline at the end (5 characters total)
$ cat foo 
test

# a hex dump of foo shows the '\n' at the end (0a)
$ xxd -p foo
746573740a

# and `stat` tells us the size of the file: 5 bytes (one for each character)
$ stat -c '%s' foo
5

# so we can use `truncate` to set the file size to 4 bytes instead
$ truncate -s 4 foo

# which will remove the newline at the end
$ xxd -p foo
74657374
$ cat foo
test$ 

サイズ変更と数学を1行のコマンドにまとめることもできます。

truncate -s $(($(stat -c '%s' foo)-1)) foo
24

受け入れられているものよりも簡単な解決策:

truncate -s -1 <<file>>

Truncate manページから:

-s, --size=SIZE
    set or adjust the file size by SIZE
SIZE may also be prefixed by one of the following modifying characters:
    '+' extend by, '-' reduce by, '<' at most, '>' at least, '/' round down
    to multiple of, '%' round up to multiple of.
37

最後の文字が改行であると確信している場合、それは非常に簡単です:

head -c -1 days.txt

head -c -N最後のNバイトを除くすべてを意味します

あなたの最善の策はPerlだと思います:

Perl -0pe 's/\n\Z//' days.txt

-0により、Perlはファイル全体を1つの大きな文字列として扱います。 -pは、プログラムを実行した後にその文字列を出力するように指示します。 -eは、「実行するプログラムはここにあります」と表示します。

正規表現\n\Zは改行と一致しますが、それが文字列の最後の文字である場合のみです。そしてs/\n\Z//は、そのような改行をまったく何も置き換えずに削除するように言っています。

上記のコマンドはファイルの新しいバージョンを出力しますが、代わりに-i( "in-place")オプションを追加することで既存のファイルを変更できます。オプションで、変更する前のファイル:

 Perl -i.bak -0pe 's/\n\Z//' days.txt

この解決策は、最後の文字がnot改行である場合、触れられないという点で安全です。このようなファイルが破損した場合でも、最後のバイトを単純に削除する他のソリューション。

12
Mark Reed

次のコマンドを試してください:sed '$ { /^$/ d}' days.txt

「最後の行が空行かどうかを確認します。そうであれば、この行を削除します」と読むことができます。私は両方のケースでテストしました:最初にファイルの最後に新しい行があり、もう1つは別の何かで終わるファイルでテストしました。

7
Lynch