Dosya adına `mv` ile yeni satır ekleyin


11

Bu ciddi bir soru. Bazı awkkomut dosyalarını test ediyorum ve adlarında yeni satır içeren dosyalara ihtiyacım var.


Dosya adına yeni satır eklemek mümkün müdür mv?

Şimdi bunu yapabilirim touch:

touch "foo
bar"

Dokunma ile kopyala yapıştır başına yeni satır karakteri ekledim. Ama fooReturnbarkabuğuma yazamıyorum .

Dosya adında yeni satır olması için dosyayı nasıl yeniden adlandırabilirim?


Düzenle 2015/06/28; 19:08

Yeni satır eklemek için zshkullanabilirim, Alt+Return


2
Neden soruyorsun? Bir arkadaşınıza şaka mı yapıyorsunuz?
Basile Starynkevitch

2
Soruyu kaldırmayın, yararlıdır. Ancak dosya adlarındaki yeni satırlardan mümkün olduğunca kaçının.
Basile Starynkevitch

2
Sizi bununla yapmaktan mvfarklı kılan şey nedir touch? Aynı şeyi denedin mi?
Kevin

2
Eh, kopyalayıp mvkomuta kolayca yapıştırabilirsiniz touch.
Kevin

2
Bu yüzden OP'nizi daha net bir şekilde formüle etmenizi öneriyorum: Belirli bir kabuk ortamında, "a [return] b" yankısında olduğu gibi tırnak içine alınmış bir dize içine yeni satır yazamıyorum.
dan

Yanıtlar:


22

Kötü bir fikirdir (dosya adlarında garip karakterler olması)

 mv somefile.txt "foo
 bar"

(ayrıca yapmış olabilir mv somefile.txt "$(printf "foo\nbar")"veya mv somefile.txt foo$'\n'bar... ayrıntılar kabuğuna özgüdür vb. kullanıyorum zsh)

Globbing hakkında daha fazla bilgi edinin , örneğin glob (7) . Ayrıntılar mermiye özgü olabilir. Ancak bunun /bin/mv (kabuğunuz tarafından), execve (2) yoluyla , genişletilmiş bir argüman dizisi verildiğini anlayın : argüman genişletme ve globbing, çağrılan kabuğun sorumluluğundadır.

Ve aynı şeyi yapmak için küçük bir C programını bile kodlayabilirsiniz:

#include <stdio.h>
#include <stdlib.h>
int main() {
  if (rename ("somefile.txt", "foo\nbar")) {
     perror("rename somefile.txt");
     exit(EXIT_FAILURE);
  };
  return 0;
}

Programın üstüne kaydet foo.c, derle ve gcc -Wall foo.c -o foo çalıştır./foo

Benzer şekilde, Perl, Ruby, Python, Ocaml, vb.

Ama bu kötü bir fikir. Dosya adlarında yeni satırlardan kaçının (kullanıcıyı karıştırır ve birçok komut dosyasını kırabilir).

Aslında, dosya yollarında yalnızca aksanlı harfleri, rakamları ve +-/._% karakterleri ( /dizin ayırıcısı olarak) kullanmanızı öneririm . "Gizli" dosyalar (ile başlayan .) dikkatli ve parcimon ile kullanılmalıdır. Bir dosya adında herhangi bir alan kullanmanın bir hata olduğuna inanıyorum. Bunun yerine bir alt çizgi kullanın (örn. foo/bar_bee1.txt) Veya eksi (ör. foo/bar-bee1.txt)


Evet, yeni satır karakteri kopyalayıp yapıştırabileceğimi biliyorum, ancak kopyalayıp yapıştırmadan bunu nasıl yapabilirim?
AB

4
Burada herhangi bir kopya veya yapıştırma yok. Sonra yazılan bir satırsonu var foo.
dan

Ancak aynı zamanda kopyala yapıştırarak çalışır
kos

1
Her zamanki dosyalar için kötü bir fikir, ancak OP'nin belirttiği gibi iyi bir test örneği.
artdanil

5
@ve (ilk pozisyonda ,olduğu -gibi) veya ' dan daha zararsız olur %. Tüm bu öneriler esas olarak bazı uygulamalarda hatalar üzerinde çalışmaktır (işletim sistemi açısından aksi takdirde geçerli olan dosya adlarını bozar). İnsanlardan hataları düzeltmek yerine bu karakterleri kullanmamalarını istemek geri geliyor.
Stéphane Chazelas


6

Bir mvçözüm istediğini biliyorum , ancak uyarıya rağmen, bu kolayca yapılabilir rename(Perl paketinde):

~/tmp$ touch foo
~/tmp$ rename 's/$/\nbar/' foo
Unsuccessful stat on filename containing newline at /usr/share/perl5/File/Rename.pm line 69.
~/tmp$ ls
foo?bar

renameÇok iyi bir fikir için teşekkürler . +1
AB

5

Bu sorunun bir yönü gerçekten hakkında değil awk- ve sadece kabuk hakkında biraz. Sorun, standart, kanonik bir tty'de çoğu zaman çekirdeğin tty disiplininin girdinizi arabelleğe almasıdır - sadece ekranınıza ve başka hiçbir yere yankılanmıyor - böylece geri boşluklu ve benzeri bir şekilde verimli bir şekilde işleyebilir.

Bununla birlikte, return tuşuna bastığınızda veya başka bir şekilde yeni satır girdiğinizde, bu tamponlanmış verilerin tümü bir kerede okuma uygulamasına - genellikle kabuğunuza - itilir. $PS2Sarkan bir alıntı girdikten sonra bunu izleyerek bunu gözlemleyebilirsiniz . Kabuk yazdırdığında $PS2, girişinizin bazı bloklarını okuduğu ve henüz geçtiğinize ikna olmadığından.

Bu nedenle, kolaylık sağlamak için ihtiyacınız olan şey \n, diğer tüm girişleri hemen itmek zorunda kalmadan terminal tamponuna bir ewline göndermenin bir yoludur. Bunu yapmak için standart yol w / anahtar dizisi olan CTRL+V- ki tırnak sonraki girdi karakteri terminali için. Daha CTRL+Vsonra yapın CTRL+J- çünkü ikincisi genellikle gerçek bir \newline'ın nasıl yazılacağıdır. Görmediğinizde işe yaradığını anlayacaksınız, $PS2çünkü kabuk hala girişinizi okumamış.

Bununla birlikte , bu girişi okuduğunda, önceki CTRL+Vsatırınızın kabuk için hiçbir fark yaratmayacağını unutmayın - bu yalnızca satır disiplini için alıntı yapar. Kesinlikle onunla anlamlı bir şey yapmak için satırsonu kabuk-alıntı yapmak isteyeceksiniz.

Bu arada, CTRL+Vbaşka şekillerde de uygulanabilir - örneğin bir kabuk kabuğuna "$(printf \\33)"bir ESCkarakter yazmanın tek yolu değildir - ve en basit olanı bile değildir. Bu şekilde ilk kaçışınızda giriş sürücüsü yorumlamaya çalışmadan klavyenizin göndereceği herhangi bir karakteri tam olarak girebilirsiniz.

Ben genellikle kabuk hiçbir şey tamamlamak için komut satırında <tab> s kullanmak istiyorum. Tamamlama yapan mermiler genellikle <tab> 'ı eşanlamlı bir şekilde yapılandıracak stty eol \t, tamamlama sistemlerinin çalışmasını sağlamak CTRL+Viçin, alışılmadık ortamlarda bile benim için çalışıyor.


2
'Ctrl + V'den bahsettiğiniz için teşekkür ederiz. Bu konuda cevap vermek üzereydim ve sonra açıklamanızı gördüm.
artdanil
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.