Shell-Script
使用 bash 在使用正則表達式的文件列表中重新格式化“#include”
考慮以下對程式碼文件進行簡單循環的程式碼:
#!/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"
更正式地說:
- 包含和文件名之間應該正好有一個空格
- 不應該有任何大寫字母,並且每個被替換的連續大寫字母序列之前都應該有一個下劃線,除非它是文件名的開頭
- 不應有任何目錄名稱
如何用 bash 做到這一點?
以下 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
)。接下來的四個 sed 表達式,所有這些都只適用於以 開頭的行
#include "
,執行以下操作:
- 去除路徑名(直到並包括最後一個斜杠);
- 將引號之間的第一個字元變為小寫;
- 在每個大寫字母的開頭,插入下劃線並將第一個字元轉為小寫;
- 擠壓下劃線可能由前面的步驟插入。
這是不完美的,但確實可以按預期翻譯您的樣本輸入。