改行なしでエコー付きのテキストを追加


14

のようなファイルにテキストを追加したいecho "abc" >>file.txt

しかし、これはabc新しい行の後に追加します

abc改行なしでエコーを使用してファイルの最後に追加するにはどうすればよいですか?


2
ファイルにはすでに改行がありますが、その直後に追加しています。したがって、最後の行の改行文字を「abc」に置き換える必要があります。
ctrl-alt-delor

StackExchangeへようこそ!あなたの質問は良いです。ファイルの内容の例(追加前、追加後に取得するもの、代わりに必要なもの)を指定した方が良いでしょう。これは、答えの1つが、abc最終的な改行なしで追加する方法であるためです。これは(質問を注意深く読んだ後)あなたが望むものではないようです。
法律

回答:


19

echo "abc" >>file.txt前ではなく、 abcに改行を入れます。abc独自の行で終わる場合は、前の改行abcがにすでに存在していたことを意味しますfile.txt

テキストファイルが改行で終わることは完全に正常であることに注意してください。UNIXでは、行はnull⁰または改行とそれに続く改行以外の文字のシーケンスで構成されます。1したがって、空でないテキストファイルはすべて改行文字で終わります。

ファイルの最後の行にテキストを追加したい場合>>、これは常にファイルに追加され、常に最後の改行の後に書き込むため、テキストを追加することはできません。代わりに、既存のファイルを変更できるツールが必要です。たとえば、sedを使用できます。

sed '$ s/$/abc/' file.txt >file.txt.new && mv file.txt.new file.txt

sedコマンドでは、最初$は「最後の行でのみ次のコマンドを実行する」ことを意味し、コマンドs/REGEX/REPLACEMENT/はREGEXをREPLACEMENTに置き換え$、行末で正規表現が一致します。

Linuxのsedコマンドには、この新しいファイルの作成と置換のシーケンスを自動化する組み込み機能があります。

sed -i '$ s/$/abc/' file.txt

これはヌルバイトで、ASCIIはNULを呼び出し、ユニコードはU + 0000を呼び出します。テキスト処理プログラムは、この文字に対処する場合としない場合があります。
1 IEEE 1003.1-2008:2016の基本定義の章の「定義」セクションにあるテキストファイル、および改行文字の定義を参照してください。


2
2番目の段落は、改行で終わらないファイルがテキストファイルではないことを意味するのですか?たとえば、新しい行で終わる既存のASCIIテキストファイルを取得し、1バイト0x41(ASCII 'A')を追加すると、技術的にはテキストファイルではなくなりますか?もしそうなら、それは一種の直感的でない定義なので、その点を強調することをお勧めします。そうでない場合は、言い回しを少し変更することで混乱を避けることができます。
デビッドZ

2
@DavidZ:Unixlandのテキストファイルの標準定義です。IIRCは、POSIXのどこかにあります。
ケビン

1
@ケビン興味深いことに、私はそれを聞いたことがありません。まあ、たとえそれが標準であったとしても、私はそれが一種の直感的でないと思います。
デビッドZ

15

echoコマンドでは不可能だと思うので、sed代わりに次のアプローチを使用してください。

sed -i '$ s/$/abc/' file.txt
  • -i-ファイルをインプレースで変更します
  • $ -最後のレコード/行を示します
  • s/$/abc/-行の終わり$を部分文字列で置き換えますabc(最後のレコードの場合)

2
「インプレース」は実際にはインプレースを意味しないことに注意してください。これは、「既存のファイルと一緒に編集したコンテンツを一時的な名前のファイルに書き込んでから置き換える」ことを意味します。これを証明するには、date >file; ls -i file; sed -i 's/201/ZZZ/' file; ls -i file
次のコマンドで

@ roaima、sedがiノード番号を変更することを知っています。
RomanPerekhrest

2
私はあなたがいるだろうと思っていましたが、私はあなたがOPナイトをインプレースすることに重点を置いて、例えば大きなファイルでの2倍のディスクスペースの使用を避けるために使用できると思いました。
ロアイマ

@roaima、夜は考える > ...と思うかもしれない-
RomanPerekhrest

13

ファイルがまだ改行で終わっておらず、テキストを追加せずにテキストを追加したい場合、-n引数を使用できます。例えば

echo -n "some text here" >> file.txt

ただし、一部のUNIXシステムにはこのオプションがありません。その場合はprintf、たとえば

printf %s "some text here" >> file.txt

(最初の%s引数は、%書式設定文字を含む追加のテキストから保護することです)

from man echo(macOS High Sierra):

-n

末尾の改行文字を印刷しません。これは'\c'、iBCS2互換システムで行われているように、文字列の末尾に追加することでも実現できます。このオプションとその影響は'\c'、IEEE Std 1003.1-2001( "POSIX.1")でCor。1-2002。最大の移植性を目的とするアプリケーションprintf(1)は、改行文字を抑制するために使用することを強くお勧めします。


これはかなり明らかにない改行で終わります。 echo -nはの終わりに改行を入れませんがabcabcそれでもユーザーが避けたいものである改行が先行します。
クサラナンダ

@Kusalananda私の答えは、OPが\n最初にスプリアスが現れないようにプロセスを変更しようとするという仮定を使用することでした。特に、変更が発生するたびにファイル全体を書き換える必要がない場合は、オプションの数が多くなります(繰り返し実行すると、かなり遅くなり、多項式時間で実行されます)。
ふわふわ

9

あなたが持っている場合はtruncate、コマンドをして、テキストファイルはその最後の文字としてNLを持っているあなたはそれを削除してから、このようなあなたのテキストを追加することができます:

truncate --size -1 file.txt
echo "abc" >>file.txt

truncateファイルの内容については何も気にしないことに注意してください。この例では、ファイルサイズを1バイト減らすだけです。最後の文字がシングルバイトでない場合、つまりマルチバイトの「ワイド」文字である場合、破損します。)


5

必要なのは、最後の行の最後に追加することです。つまり、その最後の行の区切り文字の直前、つまりファイルの最後の文字の直前に追加します。

ではksh93、次のことができます。

echo abc 1<> file >#((EOF - 1))

どこ1<>読み取り+書き込みモードでファイルを開く(そしてもっと重要なのための標準的な演算子で切り捨てずに標準出力には)と>#((...))は、ksh93固有です追求オペレータ(ここでは最後のバイトの前に追求すること)。そこにあった改行を上書きする場所をecho書き込み、独自の改行を追加することに注意してください。abc<newline>aecho

zsh同等:

zmodload zsh/system
{sysseek -w end -u 1 -1 && echo abc} 1<> file

より正確に同等の場合でも、シークに失敗するとエラーメッセージを出力する必要があります。

zmodload zsh/system
if sysseek -w end -u 1 -1; then
  echo abc
else
  syserror -p "$0: $LINENO: seek: "
fi 1<> file

-1

おそらくUUOCですが、次のこともできます。

echo "$(cat file.txt)abc" >file.txt

ジルが指摘するように、このコマンドは制限されています。

これはほとんど機能しますが、ファイルの最後にブランク行があり、直前にブランク行がある場合はそうではありません。たとえば、行数が固定されているファイルの場合、最後の行は最初は空であり、時間とともに拡張され、最後から2番目の行は空になることがあります。

さらに、cat慣れていないファイルでの使用には注意してください。

結論

sedを使用


2
これはほとんど機能しますが、ファイルの最後にブランク行があり、直前にブランク行がある場合はそうではありません。たとえば、行数が固定されているファイルの場合、最後の行は最初は空であり、時間とともに拡張され、最後から2番目の行は空になることがあります。
ジル 'SO-悪であるのをやめる'

削除する必要がありますか?私は間違いなくローマ/あなたの答えが適切な方法だと思いますが、私は個人的に代替案を見るのが好きであることを知っています、そしてOPはecho:p
jesse_b

1
また、このプットコマンドライン上のファイル全体
n.caillou

@ n.caillouハァッ?これは、STDOUTに何も出力しません。
jesse_b

2
さて、これらの脆弱性はどれも実際にはに関連していませんがcat、端末に送信される任意のエスケープシーケンスの問題に関連しています。
ilkkachu
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.