예를 들어, 구조에서 필드를 추출하려고 합니다.
typedef struct newstruct {
long id;
uint32_t vtid;
struct HN* next;
} HashNode;
sed/awk를 사용하여 구조체 이름과 구분 기호가 있는 필드를 추출하고 싶습니다.
newstruct HashNode: long id, uint_32 vtid, struct HN* next
답변1
사용이 매우 간단 awk
하며 작동할 수도 있습니다 sed
.
를 사용하면 awk
각 줄에 상태 설정/재설정이 있고 typedef
각 줄에 닫는 중괄호로 끝납니다. 적합한 awk
스크립트는 다음과 같습니다.
BEGIN {
state = 0;
typedef="";
fields="";
}
/typedef[ ]+struct/{
state = 1;
typedef=$3;
next;
}
/}.*;/ {
if (state != 0) {
sub("^.*}[ ]*","",$0);
sub(";","",$0);
sub(",$","",fields);
printf "%s %s: %s\n", typedef, $0, fields;
state = 0;
fields = "";
typedef = "";
}
next;
}
(state == 1){
gsub("[ ]+"," ", $0);
gsub(";",",",$0);
fields = fields $0;
next;
}
여기서 [
및 ]
대괄호는 공백과 탭을 묶습니다(휴대용으로 만들기 위해). 스크립트는 네 부분으로 구성됩니다.
- 이
BEGIN
작업은 변수를 초기화합니다(꼭 필요한 것은 아니지만 일부 awks는 초기화되지 않은 변수에 대해 약간 다르게 작업을 수행함). typedef
줄 뒤에 공백과 단어가 오는 패턴을 일치시킵니다struct
. 이 줄에는 세 번째 필드를 typedef의 이름으로 사용하여 최소한 3개의 필드가 있어야 합니다.- 닫는 중괄호와 일치하는 패턴입니다. 파일에 다른 항목이 있는 경우를 대비해 해당 작업은 해당 항목이
state
이미 설정되어 있는지 확인합니다. 이것이$0
현재 행입니다. 첫 번째 대체는 관심 있는 단어 앞의 모든 항목을 제거하고, 두 번째 대체는 그 뒤의 세미콜론을 제거합니다. 세 번째 대체는fields
네 번째 작업(아래)의 변수 뒤의 쉼표를 빈 문자열로 변경합니다. - 다른 모든 행과 일치하는 패턴언제
state
설정되었습니다. 이전 작업과 마찬가지로 교체를 사용하여 원하지 않는 부분을 잘라내고 먼저 여러 공백을 단일 공백으로 줄인 다음 후행 세미콜론을 쉼표로 변경합니다.
foo.awk
다음과 같이 awk를 사용하여 입력 데이터로 이 파일을 호출합니다 foo.in
.
awk -f foo.awk <foo.in
다음과 같은 줄을 일치시키려면:
struct foo {
대신에
typedef struct foo {
그러면 패턴은 다음과 같이 쓸 수 있습니다.
/^([ ]*typedef)?[ ]+struct[ ]+/{
(역시 문자 그대로 공백과 탭이 있는 대괄호). 괄호 안에 표시된 것은그룹물음표는 ?
0회 이상의 반복을 나타냅니다. (이것{
온라인은 실제로 시작을 의미합니다행동, 그러나 주어진 스크립트의 줄과 일치하도록 그대로 두었습니다.)
추가 자료:
- awk - 패턴 스캔 및 처리 언어(POSIX)
- 9.4 확장 정규식(POSIX)
답변2
sed -rn '
/typedef struct ([[:alnum:]_]+)\s+\{/!b
s//\1/; h
:X
n
/}\s+([[:alnum:]_]+)/{
s//\1/
H
g
s/;//g
s/(.*)\n(.*)\n(.*)\n(.*)\n(.*)/\1 \5: \2, \3, \4/
p;b
}
s/\s*(.+);\s*/\1/
H
bX
' file
newstruct HashNode: long id, uint32_t vtid, struct HN* next