私はライセンス/帰属コメントでソースコードファイルを複雑にするのが嫌いですが、時には要件になることもあります。したがって、数十のソースコードファイルが作成され(サブディレクトリツリーに構成されている)、各ファイルの先頭に同じ複数行コメントを追加する必要があります。
標準のGNU / Linuxコマンドラインツールを使用してこれを行うのは非常に簡単だと思います。私はこのツールを真剣に使用するのはあまりうまくいかないので、理解して助けを求めます。
私に必要なのは、すべてのtheTargetFile.txt
in ./*.txt
(サブディレクトリの再帰を含む)をcat theCommonComment.txt theTargetFile.txt
。
また、特定のマスクに合ったファイルを除外したいと思います。たとえば、すべてのファイルを考慮しますが、そのままにして*.txt
ください*.DontTouch.txt
。
find
私の考えに私にとって本当に必要な最も難しい部分は、サブディレクトリを実行し、*.txt
ファイルを含め、ファイルを除外する素晴らしいベースの注文だと思います*.DontTouch.txt
。
答え1
私が考えることができる最も簡単な方法はGNUを使用するfind
ことですbash
。sponge
その他のユーティリティ:
find dir/with/files -name '*.txt' ! -name '*.DontTouch.txt' -print0 |
while IFS= read -rd '' file; do
echo 'cat path/to/theCommonComment.txt "$file" | sponge "$file"'
done
現時点では実際に何もせずにcat
/コマンドだけを印刷します。sponge
必要なものがわからない場合は、コマンドの周囲のエコーと一重引用符を削除できます。
sponge
または、findオプションを使用しないと、-print0
このオプションがすべてのシステムで機能しない可能性があります。
find dir/with/files -name '*.txt' ! -name '*.DontTouch.txt' -exec sh '
for file; do
tempfile=$(mktemp)
cat path/to/theCommonComment.txt "$file" >"$tempfile"
mv "$tempfile" "$file"
done
' sh {} +
これを止める簡単な方法はありません。実行するジョブを印刷するだけですので注意してください。注意点 -theCommonComment.txt
ファイルが再帰操作を実行しているディレクトリにないことを確認してください(または少なくともルックアップから除外されていることを確認してください)。それ以外の場合、一部のファイルに対して2つのヘッダーが生成されます。
修正する
最後の考えは、ヘッダーがファイルに追加されたことを確認したいかもしれないということです。これは、新しいファイルを追加してコマンドを再実行する必要がある場合に便利です。また、theCommonComment.txt
検索パスにファイルを配置する問題も解決します。これら2つの解決策は次のとおりです。
comment_file=path/to/theCommonComment.txt
size=$(wc -c "$comment_file")
find dir/with/files -name '*.txt' ! -name '*.DontTouch.txt' -print0 |
while IFS= read -rd '' file; do
if [ cmp -n "$size" $comment_file" "$file" ]; do
echo 'cat "$comment_file" "$file" | sponge "$file"'
fi
done
export comment_file=path/to/theCommonComment.txt
export size=$(wc -c "$comment_file")
find dir/with/files -name '*.txt' ! -name '*.DontTouch.txt' -exec sh '
for file; do
if [ cmp -n "$size" $comment_file" "$file" ]; do
tempfile=$(mktemp)
cat "$comment_file" "$file" >"$tempfile"
mv "$tempfile" "$file"
fi
done
' sh {} +
答え2
GNU /すべてのものの最初の行の後に挿入するには:
find -name '*.txt' ! -name '*thispattern*' ! -name '*thatpattern*' \
-exec sed -si '1r TheLicense.txt' '{}' +
以前にファイルを挿入する最も簡単な方法は、少し遅く、少し混乱しています。
find -name '*.txt' ! -name '*thispattern*' ! -name '*thatpattern*' \
-exec sed -si '1{h;s,.*,cat TheLicense.txt,ep;g}' '{}' +
答え3
そしてzsh
:
zmodload zsh/mapfile
setopt extendedglob # best in ~/.zshrc
for f (Dir/**/(^*DontTouch).txt(N.))
mapfile[$f]=$mapfile[theCommonComment.txt]$mapfile[$f]
答え4
このソリューションはbash、find、tac、およびsedを使用します。
次のスクリプトをファイルにコピーし、ファイルを実行可能にします。chmod +x script
次に、次のように使用します。
./script <DIR> <HEADERFILE>
どこ
<DIR> The directory containing files ( or directory containing files..)
<HEADERFILE> The file to add on top of each file
スクリプトは次のとおりです。
#!/bin/bash
# inset a file content at the beginning of each matching files
DIR=$1
HEADER_FILE=$2
#the matching files will be ignored
IGNORE_FILE="*.DontTouch.txt"
insertHeader(){
local targetfile=$1
local headerfile=$2
echo "$targetfile"
while read line
do
# echo $line
sed -i "$targetfile" -e "1i$line\ "
done< <(tac "$headerfile")
}
export -f insertHeader
find "$DIR" -type f -name "*.txt" ! -name "$IGNORE_FILE" -exec bash -c "insertHeader {} $HEADER_FILE" \;