yeni satır olmadan yankı ile metin ekle


17

Dosyaya metin eklemek istiyorum echo "abc" >>file.txt.

Ancak bu abcyeni satırdan sonra ekleniyor

abcYeni satır olmadan yankı ile dosyanın sonuna nasıl ekleyebilirim ?


2
Dosyanın zaten yeni bir satırı var, sadece arkasından ekliyorsunuz. Bu yüzden son satırdaki yeni satır karakterini “abc” ile değiştirmeniz gerekecektir.
ctrl-alt-delor

StackExchange'e hoş geldiniz! Sorunuz iyi; dosyanızın içeriğinin örneklerini belirtmeniz daha iyi olurdu (eklemeden önce, eklemeden sonra ne elde ederseniz, bunun yerine ne istersiniz). Bunu söylüyorum, çünkü cevaplardan biri abc, (sorunuzu dikkatle okuduktan sonra) istediğiniz gibi görünmeyen son bir satırsonu olmadan nasıl ekleneceğidir .
Law29

Yanıtlar:


19

echo "abc" >>file.txtsonra abc değil , bir satırsonu koyar . Eğer abckendi çizgisiyle sonuçlanırsanız , bu daha önce yeni satırın abczaten mevcut olduğu anlamına gelir file.txt.

Bir metin dosyasının yeni satırla bitmesinin tamamen normal olduğunu unutmayın. Unix'te, bir satır null⁰ veya satırsonu dışında bir karakter dizisinden sonra bir satırsonu içerir. 1 Bu nedenle boş olmayan herhangi bir metin dosyası yeni satır karakteri ile biter.

Bir dosyanın son satırına metin eklemek istiyorsanız, bunu yapamazsınız >>, çünkü bu her zaman dosyaya eklenir , bu nedenle her zaman son satırdan sonra yazar. Bunun yerine mevcut bir dosyayı değiştirebilecek bir araca ihtiyacınız var. Örneğin, sed kullanabilirsiniz :

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

Sed komutunda birincisi $, “yalnızca son satırda aşağıdaki komutu yap” anlamına gelir, komut s/REGEX/REPLACEMENT/REGEX'i REPLACEMENT ile değiştirir ve normal ifade $satırın sonunda eşleşir.

Linux'un sed komutu, bu yeni dosya oluştur ve değiştir dizisini otomatikleştirmek için yerleşik bir özelliğe sahiptir, böylece

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

⁰ ASCII'nin NUL ve Unicode'un U + 0000'ı çağırdığı boş bir bayt. Metin işleme programları bu karakterle başa çıkabilir veya olmayabilir.
1 tanımlarını gör Metin Dosyası , Hat ve satır karakteri "Tanımlar" bölümünde Baz Tanımları IEEE 1.003,1-2008 bölüm: 2016.


2
İkinci paragrafınız, yeni satırla bitmeyen bir dosyanın metin dosyası olmadığı anlamına mı geliyor? Örneğin, yeni bir satırla biten ve tek bir bayt 0x41(ASCII 'A') ekleyen mevcut bir ASCII metin dosyasını alırsam , teknik olarak artık bir metin dosyası değil mi? Eğer öyleyse, bir nevi sezgisel olmayan bir tanım olduğu için bu noktayı vurgulamayı öneririm; değilse, ifadedeki küçük bir değişiklik karışıklığı önlemeye yardımcı olabilir.
David Z

2
@DavidZ: Unixland'daki bir metin dosyasının standart tanımı budur. IIRC bile POSIX'te bir yerlerde.
Kevin

1
@Kevin İlginç, bunu daha önce hiç duymamıştım. Standart olsa bile, sanırım bu biraz sezgisel değil.
David Z

16

Dosyanın bir satırsonu ile bitmediğini ve sadece bir satır eklemeden biraz daha metin eklemek istediğinizi varsayarsak, -nargümanı kullanabilirsiniz , örn.

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

Ancak, bazı UNIX sistemleri bu seçeneği sunmaz; bu durumda kullanabilirsiniz printf, örn.

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

(ilk %sargüman, %içinde biçimlendirme karakterleri bulunan ek metne karşı koruma sağlamaktır )

Gönderen man echo(macOS High Sierra'da):

-n

Sondaki satırsonu karakterini yazdırmayın. Bu, '\c'iBCS2 uyumlu sistemler tarafından yapıldığı gibi dizenin sonuna eklenerek de gerçekleştirilebilir . Bu seçeneğin ve etkisinin '\c'Cor tarafından değiştirildiği şekliyle IEEE Std 1003.1-2001'de ("POSIX.1") uygulama tarafından tanımlandığını unutmayın. 1-2002. Maksimum taşınabilirliği amaçlayan uygulamaların printf(1), yeni satır karakterini bastırmak için kullanılması şiddetle önerilir .


Oldukça Açıkçası gelmez bir satır ile sona erer. echo -nsonuna bir satırsonu koymaz, abcancak abcyine de kullanıcının kaçınmak istediği bir satırsonu gelir.
Kusalananda

@Kusalananda Cevabım daha çok OP'nin işlemlerini değiştirmeye çalışacağı varsayımını kullanarak \n, ilk başta sahte görünmüyordu. Daha fazla seçenek, özellikle de her değişiklik gerçekleştiğinde dosyanın tamamını yeniden yazmak zorunda kalmadıklarında daha iyidir (bu, tekrar tekrar yapılırsa oldukça yavaşlayabilir ve polinom zamanda çalışabilir).
kabarık

15

echoKomut ile mümkün olduğunu düşünmüyorum , sedbunun yerine aşağıdaki yaklaşımı kullanın:

sed -i '$ s/$/abc/' file.txt
  • -i- dosyayı yerinde değiştirme
  • $ - son kaydı / satırı göster
  • s/$/abc/- satırın sonunu $alt dize ile değiştirir abc(son kayıt için)

2
"Yerinde" gerçekten yerinde anlamına gelmez. "Düzenlenen içeriği mevcut dosyanın yanında geçici bir adlandırılmış dosyaya yazın ve sonra değiştirin" anlamına gelir. Bu ile inode bakarak bakarak kanıtlayabilirsinizdate >file; ls -i file; sed -i 's/201/ZZZ/' file; ls -i file
roaima

@roaima, sed değişen inode numarasını biliyorum.
RomanPerekhrest

2
Ben olacağını düşündüm, ama ben yerinde OP vurgusu ile , örneğin büyük bir dosya ile çift disk alanı kullanımını önlemek için kullanılabileceğini düşünüyorum endişeliydi .
roaima

@roaima, gece düşünüyorum -> düşünebilir ...
RomanPerekhrest

Abc'yi bir değişkenle değiştirmek istersem ne olur? '$ s/$/$1/'Baskıları kullanma$1
Florian Castelain

9

truncateKomuta sahipseniz ve metin dosyanızın son karakteri olarak NL varsa, onu kaldırabilir ve ardından metninizi aşağıdaki gibi ekleyebilirsiniz:

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

( truncateDosya içeriği hakkında hiçbir şey umursamaz ve bu örnekte dosya boyutunu bir bayt küçültür. Son karakteriniz tek bir bayt değilse, yani çok baytlık "geniş" bir karakterse, yolsuzluk getireceksiniz.)


5

İstediğiniz şey son satırın sonuna, yani son satırın sınırlayıcısından hemen önce, yani dosyanın son karakterinden hemen önce eklemektir.

İle ksh93şunları yapabilirsiniz:

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

Stdout'ta 1<>bir dosyayı okuma + yazma modunda (ve daha da önemlisi kesmeden ) açmak için standart operatör nerede ve >#((...))ksh93'e özgü bir arama operatörüdür (burada son bayttan önce aramak için). Not olduğunu echoyazıyor orada ve yeni satırı üzerine yazar kendi yeni satırı ekler.abc<newline>aecho

zsheşdeğeri:

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

Daha kesin bir eşdeğer olsa da, arama başarısız olduğunda bir hata mesajı yazdırmanız gerekir:

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

-1

Muhtemelen bir UUOC ama şunları da yapabilirsiniz:

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

Gilles'in belirttiği gibi bu komut sınırlıdır:

Bu çoğunlukla işe yarar, ancak bazen dosyanın sonunda boş bir satır ve hemen önce boş bir satır varsa işe yaramaz. Örneğin, son satırın başlangıçta boş olduğu ve zamanla uzandığı ve bir sonraki son satırın bazen boş olduğu sabit sayıda satır içeren bir dosya.

Ayrıca, tanımadığınız catdosyalarda kullanmaya dikkat edin:

Sonuç :

Sed kullan


2
Bu çoğunlukla işe yarar, ancak bazen dosyanın sonunda boş bir satır ve hemen önce boş bir satır varsa işe yaramaz. Örneğin, son satırın başlangıçta boş olduğu ve zamanla uzandığı ve bir sonraki son satırın bazen boş olduğu sabit sayıda satır içeren bir dosya.
Gilles 'SO- kötü olmayı bırak'

Silmeli miyim? Kesinlikle Roma / cevabını gitmek için doğru yol olduğunu düşünüyorum ama ben şahsen alternatifleri görmek gibi biliyorum ve OP istedi echo: p
jesse_b

1
Ayrıca bu, tüm dosyayı komut satırına koyar
n.caillou

@ n.caillou ha? Bu STDOUT'a hiçbir şey yazdırmaz.
jesse_b

2
Bu güvenlik açıklarının hiçbiri gerçekten ilgili değildir cat, ancak terminale rastgele kaçış dizileri gönderen sorunlarla ilgilidir .
ilkkachu
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.