Linux'ta bir dosyayı diğerine kabuktan nasıl ekleyebilirim?


418

İki dosyam var: file1ve file2. Nasıl içeriğini ekleme yapmak file2için file1içeriği böylece file1süreci devam?

Yanıtlar:


611

Bash yerleşik yeniden yönlendirme (tldp) kullanın :

cat file2 >> file1

2
Nasıl hedef dosya size ait değildir ve sudo kullanmanız gerekir?
Bijay Rungta

1
@BijayRungta: Kulağa kendi sorunuzu yanıtlamışsınız gibi geliyor. Sen önceden PEND ediyorum sudoiçin catkomuta (ve istenirse kimlik bilgilerini girin).
David

Kendinizi o dosya izinlerini yazma vermek için 777 / etc / default / liman işçisi için ... chmod ihtiyaç - eski dosya izinlerini geri mutlaka yapılması kez
danday74

1
@Sigur: Çıkışı aynı anda iki dosyaya yönlendirmenin bir yolu olmadığı sürece, komutun iki çağrılmasını içerir.
David

2
@Sigur ya bir göz teeprogramın: cat 1 | tee -a 2 3. --append(Veya -akısa olarak) geçişten sonra istediğiniz kadar dosya koyabilirsiniz .
Stefan van den Akker

291

cat file2 >> file1

>>Operatör adlı dosyaya çıktı ekler veya yoksa adlı dosya oluşturur.

cat file1 file2 > file3

Bu, iki veya daha fazla dosyayı bire birleştirir. İstediğiniz kadar kaynak dosyaya sahip olabilirsiniz. Örneğin,

cat *.txt >> newfile.txt

Güncelleme 20130902
Yorumlarda eumiro "deneme cat file1 file2 > file1." Bunun beklenen sonucu vermemesinin nedeni, yönlendirmeyi alan dosyanın, komutun solundaki komut >yürütülmeden önce hazırlanmasıdır . Bu durumda, önce file1sıfır uzunluğa kesilir ve çıktı için açılır, sonra catkomut şimdi sıfır uzunluktaki dosyayı artı file2içine içeriğini birleştirmeye çalışır file1. Sonuç, orijinal içeriğinin file1kaybolması ve yerine bir kopya olması file2muhtemeldir.

Güncelleme 20160919
Yorumlarda tpartee, destek bilgilerine / kaynaklarına bağlanmayı önermektedir. Yetkili bir referans için, tür okuyucuyu linuxcommand.org adresindeki sh man sayfasına yönlendiriyorum:

Bir komut yürütülmeden önce, girişi ve çıkışı kabuk tarafından yorumlanan özel bir gösterimle yeniden yönlendirilebilir.

Bu okuyucuya ne bilmeleri gerektiğini söylese de, aramıyorsanız ve ifade kelimesini kelime ile ayrıştırırsanız kaçırmanız kolaydır. Burada en önemli kelime 'önce' olmak. Komut yürütülmeden önce yönlendirme tamamlanır (veya başarısız olur) .

cat file1 file2 > file1Kabuk örneğinde, ilk önce yönlendirmeyi gerçekleştirir, böylece G / Ç tutamaçları, komutun yürütülmeden önce yürütüleceği ortamda yerinde olur.

Yeniden yönlendirme önceliğinin uzun süredir ele alındığı daha dostça bir versiyon, Ian Allen'ın web sitesinde Linux eğitim yazılımı şeklinde bulunabilir. Onun I / O Yönlendirme Notları sayfa yönlendirme bile komuta olmadan çalıştığını gözlem dahil konuyla ilgili söylenecek çok şey vardır. Bunu kabuğa geçirmek:

$ >out

... adlı boş bir dosya oluşturur. Kabuk önce G / Ç yönlendirmesini ayarlar, ardından bir komut arar, hiçbirini bulamaz ve işlemi tamamlar.


17
@asir - deneme cat file1 file2 > file1- bu muhtemelen beklediğiniz gibi çalışmaz.
eumiro

5
Aslında tam da buna ihtiyacı var. "Geçerli dosyanın üzerine yazmadan1" diyor. İlk üç answerers tamamen sorunun bu kısmını görmezden ve kullanan bir komut sürmüşlerdir >>hangi olacaktır dosyayı değiştirin file1. T.Rob, aslında yanlış olan bir şeyi sunmak için yarışmak yerine cevabını açıklamaktan çok daha üstün bir iş çıkardı. Sorunun metnine dayanarak, cat file1 file2 > file3bunun @asir'in aradığı uygun komut olduğuna inanıyorum .
dm78

Nazik sözler için teşekkürler David! @Eumiro'nun yukarda işaret ettiği, ancak ayrıntıya girmediği şey, sağ tarafındaki işlemin >ilk olarak gerçekleştirilmesidir. Bu nedenle, yürütme cat file1 file2 > file1önce yavaşlar file1ve şimdi sıfır uzunluktaki dosyayı kendi üzerine kopyalamaya çalışır. Bu, operasyonların gerçekleşebileceği ve gerçekleşmesi gereken sırayı düşündüğünüzde mantıklıdır, ancak birçok insanı şaşırtarak yakalayabilecek kadar incedir. Yani başka bir şey yoksa, eumiro ve siz cevabı daha da geliştirdiniz. Bunun için teşekkürler!
T.Rob

Ayrıca yok cat dosya1 >> file1 deneyin, bu şimdiye yanlışlıkla bunu ve sadece birkaç saniye içinde, 50 milyon satır sadece daha önce bir kaç düzine hatlarından dosyaya konulmuştur, dosya yinelemeli yeniden yazılması neden olur.
Hendra Uzia

Ayrıca, biraz daha özlü hale getirmek için, "yeni dosya" zaten varsa, dosyaya >> eklenir ve dosyayı > değiştirir .
rinogo

43

Not : sudo kullanmanız gerekiyorsa , bunu yapın:

sudo bash -c 'cat file2 >> file1'

sudoAyrıcalık yükselmesi çıkış yeniden yönlendirmesine aktarılmadığından, komuta basitçe alışmanın olağan yöntemi başarısız olur.


6
Bunun için başka bir ortak deyimcat file2 | sudo tee -a file1 > /dev/null
ianw


13

Sadece referans olarak, ddrescue kullanmak, örneğin büyük dosyalarınız varsa ve daha sonra bazı noktalarda duraklama ve sonra devam etme gereksiniminiz varsa görevi gerçekleştirmenin kesilebilir bir yolunu sağlar:

ddrescue -o $(wc --bytes file1 | awk '{ print $1 }') file2 file1 logfile

Önemli logfileolan. Ctrl-CAynı komutu tekrar belirterek işlemi durdurabilir logfileve devam ettirebilirsiniz; ddrescue kaldığı yerden okuyacak ve devam edecektir. -o ABayrak bayt başlamak ddrescue söyler A çıkış dosyasında ( file1). Yani wc --bytes file1 | awk '{ print $1 }'sadece file1bayt cinsinden boyutunu çıkarır (isterseniz çıktıya yapıştırabilirsiniz ls).

Yorumlarda ngks tarafından belirtildiği gibi , dezavantajı ddrescue'nun varsayılan olarak yüklenmeyeceği, bu yüzden manuel olarak yüklemeniz gerekecek. Diğer komplikasyon, depolarınızda olabilecek iki ddrescue sürümünün olmasıdır: daha fazla bilgi için bu askubuntu sorusuna bakın . İstediğiniz sürüm GNU ddrescue'dur ve Debian tabanlı sistemlerde şu paket bulunur gddrescue:

sudo apt install gddrescue

Diğer dağıtımlar için ddrescue uygulamasının GNU sürümü için paket yönetim sisteminizi kontrol edin .


1
Yeni kullanıcıların yararına: ddrescue bir GNU aracıdır, ancak Linux, Mac veya diğer unix benzeri sisteminizde bulunmayabilir. ddrescue, POSIX veya başka bir standart tarafından gerekli görülmemektedir.

2

Başka bir çözüm:

cat file1 | tee -a file2

tee istediğiniz kadar dosya ekleyebilme avantajına sahiptir, örneğin:

cat file1 | tee -a file2 file3 file3

içeriğini ekler file1için file2, file3ve file4.

Man sayfasından:

-a, --append
       append to the given FILEs, do not overwrite

0

catkolay çözüm olabilir, ancak büyük dosyaları birleştirdiğimizde çok yavaş hale gelir find -print, kediyi bir kez kullanmanız gerekse de sizi kurtarmaktır.

amey@xps ~/work/python/tmp $ ls -lhtr
total 969M
-rw-r--r-- 1 amey amey 485M May 24 23:54 bigFile2.txt
-rw-r--r-- 1 amey amey 485M May 24 23:55 bigFile1.txt

 amey@xps ~/work/python/tmp $ time cat bigFile1.txt bigFile2.txt >> out.txt

real    0m3.084s
user    0m0.012s
sys     0m2.308s


amey@xps ~/work/python/tmp $ time find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1

real    0m2.516s
user    0m0.028s
sys     0m2.204s

Find / cat combo komutunuz için bildirdiğiniz zaman tasarrufu, yalnızca dosyaların adlarını yazdıran find komutunu zamanladığınız içindir. Komutun tamamını şu şekilde zamanlamayı deneyin: time (find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1)ve yalnızca cat komutunuza benzer sonuçlar vermelidir.
JoshMc

0

catDürüst olmak gerekirse catdaha okunabilir olmasına rağmen bunu da yapabilirsiniz :

>> file1 < file2

>>Ekler STDIN için file1ve <döker file2için STDIN .



@ user202729 Haklısın, bash'de çalışmıyor. Zsh ile çalışır.
Alok Singh
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.