Shell-Script

使用 bash 在使用正則表達式的文件列表中重新格式化“#include”

  • February 6, 2017

考慮以下對程式碼文件進行簡單循環的程式碼:

#!/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 ",執行以下操作:

  1. 去除路徑名(直到並包括最後一個斜杠);
  2. 將引號之間的第一個字元變為小寫;
  3. 在每個大寫字母的開頭,插入下劃線並將第一個字元轉為小寫;
  4. 擠壓下劃線可能由前面的步驟插入。

這是不完美的,但確實可以按預期翻譯您的樣本輸入。

引用自:https://unix.stackexchange.com/questions/342696