วิธีเติมส่วนหัวของใบอนุญาตแบบซ้ำ ๆ สำหรับไฟล์. h และ. cpp ทั้งหมดในไดเรกทอรี


19

ฉันกำลังพยายามเพิ่มส่วนหัวของใบอนุญาตให้กับไฟล์ส่วนหัวและไฟล์ต้นฉบับในไดเรกทอรีโครงการโดยใช้ for loop วิธีนี้ใช้ไม่ได้มีวิธีอื่นอีกsedไหมที่ใช้?


1
กรณีที่คล้ายกันมาก: unix.stackexchange.com/questions/20577/…
pbm

คำตอบ:


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

1
มันควรจะกล่าวว่าคุณต้องเปิดglobstarในทุบตีเพื่อให้การทำงาน
Chris Down

และคุณต้องทุบตี> 4.0 (เช่น Mac OS X และ RedHat 5 ยังคงอยู่ที่ 3.X)
Matteo

11

นี่เป็นเพียงคำอธิบายเพิ่มเติมเกี่ยวกับคำตอบของDaniel Serodio'` ฉันเริ่มเขียนมันเป็นความคิดเห็น แต่มันใหญ่ขึ้นอย่างรวดเร็ว ...

สำหรับ glob shopt -s globstarทุบตีที่จะเวียนเกิดก็ต้องใช้ คุณต้องเปิดใช้งาน globstar มิฉะนั้น**จะไม่ทำงาน ตัวเลือก globstar shell ได้รับการแนะนำให้รู้จักกับ bash รุ่น 4

เพื่อหลีกเลี่ยงการประมวลผลไดเรกทอรีเช่นmy.cpp/ใช้การทดสอบ[[ -f $f ]]... เมื่อการทดสอบอยู่ในเครื่องหมายวงเล็บเหลี่ยมคู่ตัวแปรไม่จำเป็นต้องถูกยกมาสองครั้ง

นอกจากนี้คุณยังสามารถพิจารณาถึงความเป็นไปได้ที่จะไม่มีไฟล์ที่ตรงกันโดยใช้shopt -s nullglobซึ่งอนุญาตให้รูปแบบที่จับคู่ไฟล์ไม่ให้ขยายเป็นสตริง null แทนที่จะเป็นไฟล์เอง

ในการจัดการรูปแบบหลายรายการคุณสามารถโซ่รูปแบบ glob นี้**/*.cpp **/*.hแต่บางที preferrably เมื่อตัวเลือกเปลือกextglobเป็นในทางshopt -s extglobที่คุณสามารถใช้โครงสร้างดังกล่าวเป็น**/*.@(cpp|h)ที่หลีกเลี่ยงผ่านหลายช่วงระบบแฟ้ม; หนึ่งครั้งสำหรับแต่ละรูปแบบ

หากคุณต้องการ.filesที่จะรวมใช้.*.cppฯลฯ หรือใช้shopt -s dotglob

หากต้องการจัดการแก้ไขไฟล์ที่ถูกไพพ์อย่างปลอดภัยให้ใช้spongeจากแพ็คเกจmoreutils(ช่วยให้คุณไม่จำเป็นต้องสร้างไฟล์ temp ของคุณเอง)


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
n0pe

+1 แต่อย่างสง่างามสามารถจัดการโมฆะ[[ $f
enzotib

@enzotib ขอบคุณ ฉันไม่แน่ใจว่าฉันได้รับความคิดนั้นจาก มันต้องมาจากการทำงานของตัวยึดสี่เหลี่ยมจัตุรัสตัวเดียว (ไม่) ... เช่นunset x; [ -f $x ] && echo exists รายงาน "มีอยู่" ... (แก้ไข)
Peter.O

ตั้งแต่รุ่นที่ 4 ของการทุบตีไม่สำคัญ แต่ฉันจะแทนที่**/*.@(cpp|h)ด้วย$( find . -name "*.h" -name "*.cpp")
Matteo

3

ขอบคุณ @fred, @maxmackie, @enzotib

คุณช่วยกรุณาตรวจสอบขั้นตอนที่ฉันได้ปฏิบัติตาม

#!/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   

มิฉะนั้นส่วนหัวของใบอนุญาตจะถูกคัดลอกไปหลายครั้ง

โปรดแนะนำฉันรูปแบบที่จะผ่านส่วนหัวและแหล่งที่มาทั้งหมดในไดเรกทอรีโครงการและไดเรกทอรีย่อย

ฉันไม่เข้าใจสิ่งที่ @fred แนะนำอย่างสมบูรณ์


โดยทั่วไปรหัสของคุณดูโอเค ฉันจะเจาะจงมากขึ้นเกี่ยวกับการระบุตำแหน่งที่แน่นอนของ "ลิขสิทธิ์" เช่น ระบุหมายเลขบรรทัดและตำแหน่งในบรรทัดนั้น คุณสามารถป้องกันการอ่านไฟล์ทั้งหมดได้โดยการออกจากบรรทัดที่คุณคาดว่าจะพบ "ลิขสิทธิ์" ... เช่น targln=2; findln=$(sed -rne $targln'{\|// Copyright|=;q}' "$f"); if ((findln==targln));then... แต่แน่นอนเหนือกว่าสิ่งอื่นใดให้ทดสอบก่อน ... PS มันเป็นเรื่องปกติสำหรับหลักสูตรที่นี่ที่Unix & Linuxเพื่อโพสต์ความพิเศษเช่นนี้ในคำถามดั้งเดิมของคุณไม่ใช่คำตอบ ...
Peter.O

1
บางคำแนะนำ: วงเล็บลบรอบgrepเพิ่มตัวเลือกในการ-q เสมอเพิ่มคำพูดสองรอบgrep $f
enzotib

1
คำพูดมีความสำคัญมิฉะนั้นคุณจะถูกกัดโดยการแบ่งคำ ตามกฎพื้นฐานอ้างถึงการขยายทุกครั้งยกเว้นว่าคุณรู้ว่าการแบ่งคำหรือการตีความอื่น ๆ จะไม่ถูกดำเนินการโดยเชลล์
Chris Down

3

คุณสามารถทำได้ด้วยexหรือedถ้าคุณต้องการ (คุณไม่ควรทำsedตามที่คุณร้องขอsedถูกออกแบบมาเพื่อแก้ไขสตรีม-iเป็นความคิดที่ไม่ดีด้วยเหตุผลหลายประการ):

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

เหตุใดจึงเป็นsed -iความคิดที่ไม่ดี
Daniel Serodio

@DanielSerodio ตามค่าเริ่มต้นให้sed -iแบ่งการเชื่อมโยงและลิงก์ซึ่งทำให้เกิดพฤติกรรมที่ไม่คาดคิด ที่ดีที่สุดคือไม่ใช้งานง่ายและที่เลวร้ายยิ่งมันเป็นอันตราย
Chris Down

2

หากคุณมีheader_fileเนื้อหาที่ต้องการ:

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

0

บล็อกของ Gerhard Gappmeier - วิธีแทนที่ส่วนหัวไฟล์ซ้ำของไฟล์ต้นฉบับ

โพสต์บล็อกได้แนบtar.gzไฟล์ซึ่งมีไฟล์ที่จำเป็น

มันมีheader.templateไฟล์ที่คุณสามารถเขียนความคิดเห็นที่กำหนดเองมันสามารถขยายหลายบรรทัด

มันมีremove_header.awkสคริปต์ที่แทนที่ส่วนหัวที่มีอยู่ด้วยส่วนหัวใหม่

เพื่อเรียกใช้:

find . -name "*.h" -exec ~/rh/replace_header.sh {} \;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.