web-dev-qa-db-ja.com

ファイルの最後の文字を印刷する方法

Unixでは、sedのような単純なコマンドを使用して、ファイルの最後の文字を印刷する方法はありますか?

12
suvitha

テールは適切なツールであり、sedではありません。

tail -c 1 filename
32
Erik

tail -c 2 fileそれを行う必要があります。理論的には-c1であるはずですが、実践によって私は間違っていることがわかりました。

編集:ファイルに無視したい行末文字がある場合は2.1です。それ以外の場合は2.1です。

7
J.N.

これを試して cat filename | tail -c -1

4
irritate

最後の行が空でない限り、これは機能するはずです。

sed -n '$s/.*\(.\)$/\1/p' file
0
mouviciel

使用:cat test | sed -e "s/^.*\(.\)$/\1/"

ここで、testはファイルの名前です。

0
David

読者の利益のために:

問題

ここにはいくつかの誤解があります。 tail -c1 fileは確かにファイルの最後の文字を出力する正しいコマンドですが、これは、ファイルがNLで終了するかどうかを検出するために簡単に使用することはできません。シェルレベル、POSIXシェルがコマンド出力を処理する方法による:

if last_character="$(tail -c1 "$file")"; then ..
# WRONG! last_character will be empty on NL, as well as on an empty file

いくつかの不明な理由のために、POSIXは、すべての後続のNLが削除されると定義しています。世の中にあるほとんどすべてのシェルスクリプトは、次のような最も単純なものでさえ、この罠に陥る

cd "$(dirname -- "$0")" || exit           # Wrong, see: mkdir $'\n'
base="$(basename -- "$0" .sh)" || exit    # Wrong, see: mv script.sh $'\n.sh'

攻撃者は、ソフトリンクを使用してこのPOSIX標準を悪用する可能性さえあります。

これを解決する方法.. NOT

ここではbashバージョン4構文を使用していることに注意してください。

次のようなことができます:

set -o pipefail
if tail -c1 file | { IFS= read -rd '' var; postprocess "$var"; }; then ..

しかし、これはサブシェルのためにPITAです。または

6< <(tail -c1 file) IFS= read -ru6 -d '' var

これも同様に奇妙です。 (ここでtailの失敗を適切に検出する方法など)

これを正しい方法で解決する方法

しかし、以下のレシピは通常は機能します:

var="$(tail -c1 file && echo x)" && var="${var%x}" || error ..

常に余分なNLを追加するコマンド(basenamedirnameなど、ほぼすべてのコマンドがこれを実行します)の場合、これを次のように調整する必要があります。

var="$(basename -- "$file" && echo x)" && var="${var%$'\nx'}" || error ..
#----------------------------------------------------^^^^^^ change

このレシピは他の通常の状況でも機能することに注意してください。

# This is only correct here because we only expect a single filename
echo wrong > $'file'
echo right > $'file\n'
wrongname="$(fgrep -lx right file*)" || notfound
correctname="$(fgrep -lx right file* && echo x)" && correctname="${correctname%$'\nx'}" || notfound

wrongnameにはfileが含まれ、correctnameにはfile\nが含まれます(\nNLを表します)。両方のファイルが存在し、データが含まれているため、間違った内容のファイルでwrongnameバリアントを使用したというエラーはすぐには発見できません。

はい、少々気の利いたものですが、それでも必要な場合があります。

0
Tino