Bir dizindeki tüm .h ve .cpp dosyaları için lisans üstbilgisini yinelemeli olarak ekleme


19

Bir for döngüsü kullanarak bir proje dizinindeki tüm başlık dosyalarına ve kaynak dosyalarına lisans başlığı eklemeye çalışıyorum. Bu işe yaramıyor, kullanan başka bir yaklaşım var sedmı?



Yanıtlar:


14
for f in **/*.cpp; do
  cat header_file $f > $f.new
  mv $f.new $f
done

1
Bunun globstarçalışması için bash'ta açmanız gerektiği belirtilmelidir .
Chris Down

Ve bash> 4.0'a ihtiyacınız olduğunu (örneğin, Mac OS X ve RedHat 5 hala 3.X'te)
Matteo

11

Bu, Daniel Serodio'nun cevabı hakkında az çok geniş bir yorum . Bir yorum olarak yazmaya başladım, ama çok hızlı büyüdü ...

Bir bash globunun özyinelemesi için gerektirir shopt -s globstar. Globstar'ı etkinleştirmelisiniz, aksi takdirde **çalışmaz. Globstar kabuk seçeneği, bash'ın 4. sürümüne tanıtıldı.

Gibi bir dizini işlemekten kaçınmak my.cpp/için testi kullanın [[ -f $f ]]... Test çift köşeli parantez içindeyse, değişkenlerin çift tırnak içine alınması gerekmez.

Kullanarak eşleşen shopt -s nullglobdosya bulunma olasılığını da düşünebilirsiniz, bu da hiçbir dosyayla eşleşen desenlerin kendilerinden ziyade boş bir dizeye genişlemesine izin verir.

Çok sayıda kalıbı işlemek için, topak desen zincir olabilir: **/*.cpp **/*.hfakat kabuk seçeneği zaman, belki de tercihan, extglob olan ilgili yoluyla shopt -s extglob, aşağıdakiler gibi bu tür yapıları kullanabilir **/*.@(cpp|h)dosya sistemi üzerinden birden fazla geçiş kaçınan; her desen için bir kez.

Eklenmek istiyorsanız .files, .*.cppvb. Kullanın veya kullanınshopt -s dotglob

Borulmakta olan bir dosyayı güvenli bir şekilde değiştirmek için spongepaketten kullanın moreutils(size kendi geçici dosyanızı oluşturma ihtiyacını azaltır)


printf "// The License\n\n" > /tmp/$USER-license

shopt -s globstar nullglob extglob
for f in **/*.@(cpp|h) ;do
  [[ -f $f ]] && cat "/tmp/$USER-license" "$f" | sponge "$f"
done


+1, ancak [[boş bir değeri zarifçe işleyebilir $f.
enzotib

@enzotib. Teşekkürler. Bu fikri nereden aldığımdan emin değilim. Tek köşeli parantez nasıl çalışıyor olmalı (çalışmıyor) ... örneğin unset x; [ -f $x ] && echo exists "var" raporları ... (sabit)
Peter.O

Bash sürüm 4 ana akım olmadığı için henüz yerine ediyorum **/*.@(cpp|h)ile$( find . -name "*.h" -name "*.cpp")
Matteo

3

Teşekkürler @fred, @maxmackie, @enzotib.

Lütfen takip ettiğim prosedürü kontrol edebilir misiniz?

#!/bin/sh
# script to copy the headers to all the source files and header files
for f in *.cpp; do
  if (grep Copyright $f);then 
    echo "No need to copy the License Header to $f"
  else
    cat license.txt $f > $f.new
    mv $f.new $f
    echo "License Header copied to $f"
  fi 
done   

aksi takdirde lisans başlığı birden çok defa kopyalanır.

Lütfen proje dizini ve alt dizinlerindeki tüm üstbilgileri ve kaynakları incelemek için bir model önerin.

@Fred'nin ne önerdiğini tam olarak anlayamadım.


Genel olarak, kodunuz iyi görünüyor. Örneğin, "Telif Hakkı" nın tam yerini belirleme konusunda daha spesifik olurum. satır numarasını ve bu satırdaki konumu belirtin. "Telif Hakkı" nı bulmayı beklediğiniz satırdan çıkarak dosyanın tamamını okumanızı engelleyebilirsiniz ... örn. targln=2; findln=$(sed -rne $targln'{\|// Copyright|=;q}' "$f"); if ((findln==targln));then... ama elbette, her şeyin üstünde ve ötesinde, önce iyice test edin ... PS. O burada ders için eşit olduğunu Unix ve Linux bu tür post ekstralar , orijinal söz konusu değil ... bir cevap olarak
Peter.O

1
Bazı tavsiyeler: parantezleri kaldırın grep, -qseçeneğine ekleyin grep. Etrafınıza her zaman çift tırnak ekleyin $f.
enzotib

1
Alıntılar yaşamsaldır, aksi takdirde kelime bölme tarafından ısırılırsınız. Temel bir kural olarak, kelime bölme veya diğer yorumların kabuk tarafından gerçekleştirilmeyeceğini bilmediğiniz sürece her genişletmeyi alıntılayın.
Chris Down

3

Bunu ile exya edda tercih ederseniz yapabilirsiniz (bunu istediğiniz gibi yapmamalısınız sed, sedakışları düzenlemek için tasarlanmıştır, -içeşitli nedenlerden dolayı kötü bir fikirdir):

shopt -s globstar

for _file in **/*.@(cpp|h); do
    ed -s "${_file}" << EOF
0a
/* This file is licensed under the foo license.
   All copyright strictly enforced by the copyright monster. */
.
w
EOF
    done

Neden sed -ikötü bir fikir?
Daniel Serodio

@DanielSerodio Varsayılan olarak, sembol bağlantılarını sed -ive sabit bağlantıları keserek beklenmeyen davranışlara neden olur. En iyi ihtimalle sezgisel değildir, daha da kötüsü aktif olarak zararlıdır.
Chris Down

2

header_fileİstediğiniz içeriğe sahip bir a'nız varsa:

find -name '*.cpp' -exec bash -c 'cat header_file \{} > \{}.new; mv \{}.new  \{}' \;
find -name '*.h' -exec bash -c 'cat header_file \{} > \{}.new; mv \{}.new  \{}' \;

1
#!/bin/bash

for i in `find . -name '*.[m|h]'` # or whatever other pattern...
do
  echo $i
  if ! grep -q Copyright $i
  then
    cat copyright.txt $i >$i.new && mv $i.new $i
  fi
done
enter code here

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.