X는 {0,40,80,...,200}에 있는 "time: X" 텍스트 뒤에 오는 100줄을 가져오려고 합니다. 이것이 내가 지금까지 가지고 있는 것입니다:
#!/bin/bash
start=1
end=5
for i in $(seq $start $end);do
j=$(($i*40))
awk '/time: $j/{for(i=1;i<=100;i++}{getline;print}}' file > fileX-$j.txt
done
그러나 이것은 작동하지 않는 것 같습니다. 내 질문은 특히 변수 $j에 관한 것이며 '/time: ...' 뒤에 변수를 정의해야 하는 방법에 관한 것입니다.
예를 들어 "file"이라는 파일이 있습니다.
time: 1
1 2 3
1 33 1
2 31 4
time: 40
2 1 3
9 8 77
1 3 4
이 경우에는 두 개의 별도 파일을 만들고 싶습니다.
1 2 3
1 33 1
2 31 4
두 번째는 다음과 같습니다.
1 2 3
1 33 1
2 31 4
mazs가 언급한 것처럼 $j를 변수로 전달하려고 시도했지만 여전히 빈 파일이 제공됩니다. 내가하는 방법은 다음과 같습니다.
awk -v jj=$j '/time: jj/{for(i=1;i<3;i++){getline;print}}' file > fileX-$j.txt
답변1
두 가지 질문이 있습니다. 첫 번째는 쉘이 $j
작은따옴표 내에서 확장되지 않는다는 것입니다. 즉, 변수 값이 아닌 '$j'
문자열을 원한다고 쉘에 알립니다 .$j
j
이 경우 값에는 숫자만 포함되므로 작은따옴표 밖에 넣을 수 있습니다.
awk '/time: '"$j"'/{for(i=1;i<=100;i++}{getline;print}}' file > fileX-"$j".txt
j
값에 정규식 특수 문자( .
등) 가 포함된 경우 *
해당 문자는 그렇게 해석됩니다. 예를 들어
j='2*3'
awk '/foo '"$j"' bar/'
스크립트는 대신 , 등 foo 3 bar
을 foo 23 bar
포함 하는 줄을 인쇄합니다 . 값에 awk가 있으면 예를 들어 정규식 일치 구조의 끝이 표시됩니다.foo 223 bar
foo 2*3 bar
/
j='2/3'
awk '/foo '"$j"' bar/'
토큰 시퀀스 /foo 2/
, 3
, bar
가 /
구문상 올바르지 않다고 awk에서 불평하게 됩니다.
명령줄 옵션을 사용하여 awk에 대한 변수를 정의할 수 있습니다 -v
.
j='a\tb'
awk -v j="$j" '{print j}'
이 값 쌍은 백슬래시 확장을 수행합니다 j
. 예를 들어 위의 코드 조각은 각 줄을 a↦b
탭 ↦
문자로 바꿉니다.
그러나 awk는 내부 변수를 확장하지 않기 때문에 이는 귀하의 경우에 직접 적용되지 않습니다 /…/
. 이는 변수의 값이 아니라 /foo/
string 과 일치합니다 . 정규식 일치에 변수를 사용하려면 다음 함수를 사용해야 합니다 .foo
foo
match
awk -v j="$j" 'match($0, "time: "+j) {for(i=1;i<=100;i++}{getline;print}}' file > fileX-"$j".txt
이는 j
백슬래시가 포함되지 않은 값에 적용됩니다. 예를 들어 j
로 설정 하면 등 a/b*c
의 행과 일치합니다. 로 설정 하면 뒤에 공백과 탭이 포함된 행 과 일치합니다 .time: a/c
time: a/bc
j
\t
time:
쉘 변수의 값을 awk에 전달하려면 값이 무엇이든 환경을 통해 전달하십시오.
export j
awk 'match($0, "time: "+j) {for(i=1;i<=100;i++}{getline;print}}' file > fileX-"$j".txt
또는 j
나머지 스크립트가 진행되는 동안 환경에 갇히지 않으려면 다음을 수행하세요.
j="$j" awk 'match($0, "time: "+j) {for(i=1;i<=100;i++}{getline;print}}' file > fileX-"$j".txt
정규식 대신 리터럴 문자열을 검색하려면 index
대신 이 함수를 사용할 수 있습니다 match
.
j='a*b'
awk 'index($0, "time: "+j)'
인쇄에는 가 포함되어 있습니다 time: a*b
.
답변2
$j 쉘 변수를 awk에 전달해야 합니다:
awk -v jj="$j" '...'
인수에 백슬래시 확장이 적용되므로 변수 값에 백슬래시가 포함되어 있지 않다고 가정합니다 awk -v
.