:için başka bir isim true. Her ikisi de bash'deki kabuk yapılarıdır, ama hayır /bin/:, sadece a /bin/true. Çıktı yönlendirme, kabuğun open(2)dosyaya gitmesine neden olur O_CREAT|O_TRUNC. Hiçbir şey yazılmazsa, sıfır uzunlukta kalır.
Bu iki parçayı bir araya getirmek, :> filedosyaları kesmek için oldukça yaygın bir deyimdir. : >fileYine de çoğu insan daha az garip görünmeye çalıştı .
2. satır hakkında bir yorumda bulunduğunuzdan, yorumlarımı bir cevaba dönüştüreceğim. (Sorunuzda bunu sormamış olsanız bile.)
2. satır, satırları otherfileadlandırılmış değişkenlere okuyan bir döngüdür . Döngü gövdesi, daha önce sahip oldukları boşluklardan ziyade ayırıcılarla echoyazdırmak için kullanır ;. fileher yinelemede kapatılır ve yeniden açılır (ekleme için), çünkü yönlendirme döngü içindedir. Kullanmak while ...;do read -r ...;done <otherfile >filedaha az emer ve önce dosyayı kesmek zorunda kalmaz. kaçış karakteri olarak read -ryemek yemiyor \.
Bash'taki metin işleme oldukça yavaştır. Bunun bir kısmı kaçınılmaz: Bir satırın sonunu aşmamak için her readdefasında bir bayt ( read(2)bayt başına bir sistem çağrısı) gitmek zorunda. İş için doğru aracı kullanmak daha iyi olacaktır:
awk -vOFS=';' '{ print $1, $2, $4, $5, $3 }' -- otherfile >file
--otherfileaptalca bir şey olarak adlandırılırsa betiğinizin kırılmadığı anlamına gelir --version.
Çıktı Alanı Ayırıcısını ayarlamak, ;yazdırmak için yalnızca birden çok alanı iletebileceğiniz anlamına gelir. Shell read, satırın geri kalanının tamamını beyaz boşluk ile son değişkene atar, ancak awk'ye yalnızca 5'e ayrılmasını söylemenin bir yolu yoktur. Perl bunu kolaylaştırır, çünkü splitmax-field argümanını alabilir, ancak başlamak için awk'den çok daha yavaştır.
Aslında, o kadar da zor değil, sadece çirkin bir regex yazmak oldu. $5Awk yerine satırın geri kalanını almak için , alanlar üzerinde dolaşmak orijinal boşluklarını hala kaybeder. Benim ilk canlı bir fikir kullanmaktır gensubüzerinde $0kalan her şeyi bırakarak (yani olmayan uzay boşluğundan sonra) ilk 4 alanlarını kaldırmak için (tam çizgi):
awk -vOFS=';' '{ tail = gensub("[[:space:]]*([^[:space:]]+[[:space:]]+){4}", "", 1); print $1, $2, $4, tail, $3 }' -- otherfile >file
İlk denemede doğru yaptım, ama bunun için kendimden etkilendim gerçeği, bu awk kodunun okunabilirliği hakkında bir şeyler söylüyor. >. <
Daha printönce olduğu gibi, ancak bunun yerine nasıl olduğuna taildikkat edin $5.
echo 'A B c DD e f g f' |
awk -vOFS=\; '{ tail = gensub("[[:space:]]*([^[:space:]]+[[:space:]]+){4}", "", 1);
print $1, $2, $4, tail, $3 }'
A;B;DD;e f g f;c
Değişmezi kopyalayıp / yapıştırabilir ve çıktıda ortaya çıktığını gösterebilseydim bu daha etkileyici olurdu. ^ Q ile bash içinde bir tane yazın. ctrl-Q Bir sonraki tuşa basmaya hazır bir karakter olarak alıntı yapın, çünkü bash emacs tarzı çizgi düzenleme işlemi bunun için gerçek emaclerle aynıdır.
http://mywiki.wooledge.org/BashFAQ , senaryoda attığınız veri veya dosya adlarından bağımsız olarak, komut dosyası oluşturma konusunda bazı yararlı şeyler içerir.
:>olan tek bir operatör değil. Bunun: > fileyerine okursanız anlaşılması daha kolay olabilir .