
예를 들어, 구조에서 필드를 추출하려고 합니다.
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
은 변수를 초기화합니다(꼭 필요한 것은 아니지만 일부 awk는 초기화되지 않은 변수에 대해 약간 다른 작업을 수행함). - 와 일치하는 패턴
typedef
, 그 뒤에 공백 및 단어가 옵니다struct
. 세 번째 필드를 typedef의 이름으로 사용하여 한 줄에 최소한 3개의 필드가 있어야 합니다. - 닫는 중괄호와 일치하는 패턴입니다. 파일에 다른 내용이 있는 경우를 대비하여 작업이
state
설정되었는지 확인합니다. 현재$0
라인입니다. 첫 번째 대체는 관심 있는 단어 앞의 모든 내용을 제거하고 두 번째 대체는 그 뒤에 오는 세미콜론을 제거합니다. 세 번째 대체는 네 번째 작업(아래)에서 나온 변수 뒤의 쉼표를fields
빈 문자열로 변경합니다. - 다른 모든 라인과 일치하는 패턴언제
state
설정됩니다. 이전 작업과 마찬가지로 이 작업은 대체를 사용하여 원하지 않는 부분을 잘라냅니다. 먼저 여러 공백을 단일 공백으로 줄인 다음 후행 세미콜론을 쉼표로 변경합니다.
다음과 같이 awk를 사용하려면 해당 파일 foo.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