Tôi đang cố gắng thêm tiêu đề giấy phép cho tất cả các tệp tiêu đề và tệp nguồn trong thư mục dự án bằng vòng lặp for. Điều này không hiệu quả, có cách tiếp cận nào khác sed
không?
Tôi đang cố gắng thêm tiêu đề giấy phép cho tất cả các tệp tiêu đề và tệp nguồn trong thư mục dự án bằng vòng lặp for. Điều này không hiệu quả, có cách tiếp cận nào khác sed
không?
Câu trả lời:
for f in **/*.cpp; do
cat header_file $f > $f.new
mv $f.new $f
done
globstar
bash để làm việc này.
Đây ít nhiều chỉ là một bình luận mở rộng về câu trả lời của Daniel Serodio . Tôi bắt đầu viết nó như một bình luận, nhưng nó nhanh chóng phát triển quá lớn ...
Để một bash toàn cầu được đệ quy, nó đòi hỏi shopt -s globstar
. Bạn phải kích hoạt globalstar, nếu **
không thì không hoạt động. Tùy chọn shell globalstar được giới thiệu cho phiên bản 4 của bash.
Để tránh xử lý một thư mục như my.cpp/
, hãy sử dụng kiểm tra [[ -f $f ]]
... Khi kiểm tra nằm trong dấu ngoặc vuông, các biến không cần phải được trích dẫn kép.
Bạn cũng có thể xem xét khả năng không có tệp phù hợp bằng cách sử dụng shopt -s nullglob
, cho phép các mẫu không khớp với tệp nào mở rộng thành chuỗi null, thay vì chính chúng.
Để xử lý nhiều mẫu, bạn có thể chuỗi các mẫu glob: **/*.cpp **/*.h
, nhưng có lẽ tốt hơn là, khi vỏ tùy chọn extglob là trên qua shopt -s extglob
, bạn có thể sử dụng các cấu trúc như vậy như **/*.@(cpp|h)
mà tránh nhiều đi ngang qua hệ thống tập tin; một lần cho mỗi mẫu.
Nếu bạn muốn .files
được bao gồm, sử dụng .*.cpp
vv, hoặc sử dụngshopt -s dotglob
Để xử lý một cách an toàn việc sửa đổi tệp đang được xử lý, hãy sử dụng sponge
từ gói moreutils
(nó giúp bạn tiết kiệm được nhu cầu tạo tệp tạm thời của riêng bạn)
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
[[
duyên dáng có thể xử lý null $f
.
unset x; [ -f $x ] && echo exists
báo cáo "tồn tại" ... (đã sửa)
**/*.@(cpp|h)
bằng$( find . -name "*.h" -name "*.cpp")
Cảm ơn bạn @fred, @maxmackie, @enzotib.
Bạn có thể vui lòng kiểm tra các thủ tục tôi đã làm theo.
#!/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
nếu không, tiêu đề giấy phép sẽ được sao chép thành nhiều lần.
Vui lòng gợi ý cho tôi một mẫu để đi qua tất cả các tiêu đề và nguồn trong thư mục dự án và thư mục con.
Tôi không thể hiểu đầy đủ những gì @fred đã đề xuất.
targln=2; findln=$(sed -rne $targln'{\|// Copyright|=;q}' "$f"); if ((findln==targln));then
... nhưng, tất nhiên, trên hết và hơn tất cả mọi thứ khác, hãy kiểm tra kỹ lưỡng trước ... PS. Đây là ngang bằng với khóa học tại Unix & Linux để đăng các phần bổ sung như vậy trong câu hỏi ban đầu của bạn, không phải là một câu trả lời ...
grep
, thêm -q
tùy chọn vào grep
. Luôn luôn thêm dấu ngoặc kép xung quanh $f
.
Bạn có thể làm điều này với ex
hoặc ed
nếu bạn thích (bạn không nên làm điều này với sed
yêu cầu của bạn, sed
được thiết kế để chỉnh sửa luồng, -i
là một ý tưởng tồi vì nhiều lý do):
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
một ý tưởng tồi?
sed -i
phá vỡ liên kết tượng trưng và liên kết cứng, dẫn đến hành vi không mong muốn. Tốt nhất là nó không trực quan, tệ hơn là nó có hại tích cực.
#!/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
Blog của Gerhard Gappmeier - Cách thay thế đệ quy các tiêu đề tệp của các tệp nguồn
Bài đăng trên blog đã đính kèm một tar.gz
tệp, chứa các tệp cần thiết.
Nó có một header.template
tập tin, nơi bạn có thể viết một bình luận tùy chỉnh, nó có thể trải dài trên nhiều dòng.
Nó có một remove_header.awk
kịch bản thay thế các tiêu đề hiện có bằng tiêu đề mới.
Để chạy nó:
find . -name "*.h" -exec ~/rh/replace_header.sh {} \;