Çıkışı yalnızca son değil tüm komutlardan dosyaya yönlendirin


11

Yankılı bir dosyaya üstbilgi eklemek istiyorum, daha sonra dosyanın geri kalanını oluşturmak için bir komut kullanın. Bu, iki ayrı komut kullanacağım anlamına geliyor.

Her iki komuttan çıktıyı yeniden yönlendirmeli bir dosyaya nasıl yazabilirim?

denedim

echo "header line" | cut -c 1-5 input_file > output_file

echo "header line"; cut -c 1-5 input_file > output_file

Bu yalnızca çıkışı cut komutundan yönlendirir.

Aşağıdaki komut çalışır, ancak beceriksiz hisseder:

echo "header line" > output_file; cut -c 1-5 input_file >> output_file

Sorunumu çözmenin akıllı yolu nedir?

Yanıtlar:


11

Buradaki sorun Linux yönlendirmesi ile ilgili bir sorun değil; bunun yerine, boru hattının nasıl çalıştığının temel bir yanlış anlaşılmasıdır. Buradaki yönlendirme çalışmıyor çünkü sadece kesim aslında stdout'a yazdırıyor. echo komutu için stdout, cut'un stdinine (bir dosya belirtildiğinden bu durumda kullanılmaz) kesilmiştir.

echo "header line" > output_file && cut -c 1-5 input_file >> output_file

İstediğiniz ve hiç inelegant değil ne (yerime başkasının senin ;ile &&öylesine başlık başarıyla yazıldıysa kesim komutu yalnızca yürütme anlamına, aynı çalıştırmaz bu şekilde size çıkış_dosyası oluşturmak için izinleri veya yazma yoksa ).

Bunların tümünü bir alt kabukta da yapabilirsiniz, örn.

(echo "header line"; cut -c 1-5 input_file) > output_file

ancak bunu yapmanın gerçek bir yararı yoktur ve daha karmaşık örneklerle, alt kabuğun kapsamının ne olduğunu bilmiyorsanız sorunlara neden olabilir.

Kesimi stdin'den stdout'a geçirmek istiyorsanız deneyebilirsiniz:

echo "header line" | cut -c 1-5 - input_file

(Çizgi stdin için ortak bir kısayoldur)

Bununla birlikte, bu aynı zamanda stdin üzerinde kesme işlemini de gerçekleştirecektir ("başlık" başlık çizgisine yol açar). Sorundan istediğini bu olup olmadığını söylemek zor.


13

Aradığın şey:

{ echo "header line"; cut -c 1-5 input_file; } > output_file
  • Komutlar alt kabukta değil, geçerli kabukta yürütüldüğünden bu sözdiziminin yan etkisi yoktur
  • Output_file dosyasına giden komutların açık bir şekilde sınırlandırılması var
  • Bu şekilde yeniden yazabileceğiniz gibi iyi ölçeklenir:

{
  echo "header line"
  cut -c 1-5 input_file
  ... # insert new commands here
} > output_file

Hata çıkışının aynı dosyaya gitmesini istiyorsanız, son satırı şu şekilde değiştirebilirsiniz:

} > output_file 2>&1

Bu ipucunu hatırlattığı için Olivier Dulac'a teşekkürler.

Blok içindeki bazı çıktıların ekranınıza gitmesini istiyorsanız, bu sözdizimini kullanabilirsiniz:

{
  echo "header line"
  echo "this line doesn't go to output_file" > /dev/tty
  cut -c 1-5 input_file
} > output_file

+1: daha net ve neye nereye yönlendirildiğini açıkça tanımlar. (Hata msj dahil) her şeyi yönlendirmek için: { .... } > some_file 2>&1( "clobber" some_file değil clobber ancak ekleme kendisine bunun yerine, sadece değiştirmek olacaktır. >Bir içine >>: { ... } >> some_file 2>&1)
Olivier Dulac

4

Sadece cevapları tamamlamak için exec var.

exec > output_file
echo "header line"
cut -c 1-5 input_file

+1: komut dosyalarında bunu kullanmak çok yaygın (komut satırında daha az, işler kafa karıştırmaya başladığında ^^)
Olivier Dulac

Birisi bu çözümü ayrıntılı olarak açıklayabilir mi? Ne yaptığını görebiliyorum ama bu bağlamda 'exec' anlamıyorum. Ayrıca, komut dosyanızın geri kalanının normal stdout'a ihtiyacı varsa tekrar kapatmak zorunda olduğunuz bir şey gibi görünüyor.
Joe

1
exec komut dosyası olmadan bir komut dosyasında kullandığınızda, geçerli kabuğu ve gelecekteki tüm çocukları etkileyen exec üzerinde G / Ç yeniden yönlendirmesi yapabilirsiniz.
Hildred

Teşekkürler. Bunu daha önce görmedim. Bence çok faydalı olacak.
Joe
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.