コードファイルに対して簡単なループを実行する次のコードを考えてみましょう。
#!/bin/bash
dir="."
find $dir -name *.cpp -o -name *.h | while read file; do
echo "processing: "$file
# Process file here
done
すべてのファイルは、次のような汚れたインクルードで始まります。
#include<iostream>
#include <vector>
#include"this_is_file1.h"
#include "this_is_file2.h"
#include "This_Is_File3.h"
#include"thisIsFile4.h"
#include "ThisIsFile5.h"
#include"dir/thisIsFile6.h"
#include "dir/ThisIsFile7.h"
#include "dir/ThisIsFile8.txx"
#include "dir/ThisIsFILe9.txx"
このように変換して(既存のファイルを上書きしたい)
#include <iostream>
#include <vector>
#include "this_is_file1.h"
#include "this_is_file2.h"
#include "this_is_file3.h"
#include "this_is_file4.h"
#include "this_is_file5.h"
#include "this_is_file6.h"
#include "this_is_file7.h"
#include "this_is_file8.txx"
#include "this_is_file9.txx"
より形式的に:
- インクルードとファイル名の間には正確に1つのスペースが必要です。
- 大文字があってはいけません。ファイル名の先頭でない限り、連続した大文字に置き換えられた各文字列の前に下線を付ける必要があります。
- ディレクトリ名があってはなりません。
Bashでこれを行う方法は?
ベストアンサー1
次のsedスクリプトはこれを行う必要があります。
s/\(#include\) *\([^ ]\+\)/\1 \2/
/^#include "/ {
s/".*\//"/
s/"\(.\)/"\l\1/g
s/\([^A-Z]\)\([A-Z]\)/\1_\l\2/g
s/_\+/_/g
}
次のコマンドを実行してファイルに適用できます。
sed -i.bak -f fix.sed input...
(これは上記のスクリプトが呼び出され、fix.sed
後で必要な数のファイルを引数として提供できることを前提としています。.bak
バックアップを作成したくない場合は削除してください。)
最初のsed代替式は、空の空白#include
(\ *
)と実行を一致させ、その実行を単一の空白に置き換えます。また、[^ ]\+
行の残りの部分()を小文字に変換します(使用\l
)。
次の4つのsed式(すべてで始まる行にのみ適用されます#include "
)は、次のことを行います。
パス名を削除します(最後のスラッシュまでのすべての項目)。
引用符の間の最初の文字を小文字に変換します。
各大文字グループの先頭に下線を挿入し、グループの最初の文字を小文字に変換します。
前の手順で挿入された可能性がある下線を押し出します。
完璧ではありませんが、入力例を期待どおりに変換します。