파일 이름이 "pretempsc.cfg"인지 확인하고 해당 내용을 그대로 인쇄해야 하는 스크립트 코드는 다음과 같습니다. . 다른 파일의 경우 "abc 비활성화..."로 시작하는 줄만 "no abc..."로 수정해야 합니다.
#!/bin/sh
IN_FILE=$1
OUT_FILE=$2
WhatFileIsIt() {
awk -v filename=$IN_FILE '
BEGIN {
scnode = 0;
if (filename == "pretempsc.cfg") {
scnode = 1; }
}
{
if (!scnode) {
/^abc disable/ {
print "no abc "$4"";
next;
}
print;}
}
else {print}
}
'
}
cat $IN_FILE | WhatFileIsIt | cat > $OUT_FILE
이 스크립트를 실행할 때 다음 오류가 발생합니다.
awk: cmd. line:9: /^abc disable/ {
awk: cmd. line:9: ^ syntax error
awk: cmd. line:16: else {print}
awk: cmd. line:16: ^ syntax error
내가 찾은 바로는 액션 블록에서 if 및 조건부 액션을 잘못 사용한 것 같지만 정확히 무엇이 잘못되었는지는 알 수 없습니다.
참고: 쉘 스크립트에서 awk를 사용해야 했고, IN_FILE을 자체적으로 처리하는 WhatFileIsIt과 같은 다른 함수도 많이 있었습니다.
답변1
예, 해당 패턴 일치를 전체 문으로 변경해야 합니다 if
.
if (/^abc disable/) {
print "no abc "$4"";
next;
}
( /pattern/
예 $0 ~ /pattern/
, $0
전체 입력 줄을 포함하는 약어입니다.)
print
그 이후에 입력된 네 번째 열만 인쇄되므로 just no abc
가 abc disable foo bar doo
됩니다 no abc bar
. 이것이 당신이 원하는 것인지 잘 모르겠습니다.
이 작업을 수행하는 동안 몇 가지 다른 사항이 떠오릅니다. 너무 명확하거나 스크립트의 나머지 부분과 충돌하는 경우 무시해도 됩니다. (너무 많은 실수를 저지르지 않기를 바랍니다.)
끝에 추가 닫는 중괄호가 있는 것 같고 print
가장 깊은 조건의 들여쓰기가 약간 벗어난 것 같아서 조금 다시 작성합니다.
{
if (!scnode) {
if (/^abc disable/) {
print "no abc " $4;
next;
}
print;
} else {
print;
}
}
그러나 여기서부터 특별한 일을 하는 유일한 시간은 둘 다 !scnode
참이고 /^abc disable/
일치하는 경우이며, 다른 모든 경우에만 print
조건을 결합할 수 있습니다 &&
(물론 서로 다른 유형의 파일 간의 분리는 더 이상 필요하지 않습니다) . 매우 명확합니다).
{
if (!scnode && /^abc disable/) {
print "no abc "$4"";
next;
} else {
print;
}
}
next
실행 시간을 단축시키는 a가 있기 때문에 final은 절 없이 그대로 유지 print
될 수 있고 else
, 실제로 전체 코드 블록이 하나이기 때문에 if
조건문을 메인 레벨에 올려놓고 무조건 기본 인쇄 작업을 수행할 수 있습니다.
!scnode && /^abc disable/ {
print "no abc "$4"";
next;
}
1;
(물론 지금은 좀 너무 깔끔해 보일 수도 있습니다.)
또한 쉘 스크립트에서는 고양이를 방해할 필요가 없습니다. 고양이를 잠들게 하고 리디렉션을 위해 쉘을 사용하는 것이 더 좋습니다. (그리고 쉘 변수를 인용하십시오.)
WhatFileIsIt < "$IN_FILE" > "$OUT_FILE"
함수의 이름은 약간 혼란스럽습니다. 실제로 "무엇"에 대한 질문에 대답하지 않고 파일을 처리합니다. 어쩌면 비슷한 것일까요 ProcessFile
?
글쎄, 함수에 대해 말하자면, 함수는 IN_FILE
로컬이 아닌 변수를 사용합니다. 서로 다른 두 파일에 대해 함수를 실행해야 하는 경우 혼란스러울 수 있습니다. 쉘 스크립트 자체와 마찬가지로 함수도 매개변수를 사용하여 호출할 수 MyFunction foo
있으며 함수 내에 $1
포함될 수 있습니다 .foo
그래서 나는 아마도 다음과 같은 일을 할 것입니다
ProcessFile() {
awk < "$1" -v filename="$1" '
[...]
(입력 리디렉션을 awk 명령줄 중간에 배치하든지 끝에 배치하든 상관없습니다.)
다음과 함께 사용:
ProcessFile "$IN_FILE" > "$OUT_FILE"