
다음은 파일 이름이 '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
거기는 입력의 네 번째 열만 인쇄하므로 no abc
just abc disable foo bar doo
로 바뀐다는 점에 유의하세요 no abc bar
. 이것이 당신이 원하는 것인지 잘 모르겠습니다.
그 과정에서 다른 것들이 떠오릅니다... 너무 명백하거나 스크립트의 나머지 부분과 충돌하는 경우에는 무시해도 됩니다. (그리고 제가 너무 많은 실수를 저지르지 않았으면 좋겠습니다.)
끝 부분에 추가 오른쪽 중괄호가 있는 것 같고 print
가장 깊은 조건의 들여쓰기가 약간 벗어난 것 같아서 약간 다시 작성합니다.
{
if (!scnode) {
if (/^abc disable/) {
print "no abc " $4;
next;
}
print;
} else {
print;
}
}
그러나 여기에서 보면 특별한 작업이 수행되는 유일한 경우는 둘 다 !scnode
true이고 /^abc disable/
일치하는 경우이고, 다른 모든 경우에는 print
. 따라서 우리는 다음과 같은 조건을 결합할 수 있습니다. &&
(물론 서로 다른 유형의 파일 간의 구분은 더 이상 명확하지 않습니다.)
{
if (!scnode && /^abc disable/) {
print "no abc "$4"";
next;
} else {
print;
}
}
실행을 짧게 하는 a가 있기 때문에 next
최종은 절 print
없이도 유지될 수 else
있으며 실제로 전체 코드 블록은 단지 an이므로 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"