![두 파일 사이의 문자열 값 바꾸기](https://linux55.com/image/77771/%EB%91%90%20%ED%8C%8C%EC%9D%BC%20%EC%82%AC%EC%9D%B4%EC%9D%98%20%EB%AC%B8%EC%9E%90%EC%97%B4%20%EA%B0%92%20%EB%B0%94%EA%BE%B8%EA%B8%B0.png)
파일 1의 포먼트 [1]의 주파수와 대역폭을 파일 2의 포먼트 [1]의 주파수와 대역폭으로 바꾸고 싶습니다. 이 교체는 n 프레임에 대해 수행되어야 합니다. 유닉스 스크립트를 통해 이를 수행하는 방법은 1000프레임입니다. 도와주세요.
파일 1:
frames []:
frames [1]:
intensity = 0.006356559616564358
nFormants = 5
formant []:
formant [1]:
frequency = 403.06628436252515
bandwidth = 160.21467462436982
formant [2]:
frequency = 1507.54711702621
bandwidth = 519.232413949129
formant [3]:
frequency = 2577.174907989416
bandwidth = 1535.5870557191413
formant [4]:
frequency = 3764.624274996511
bandwidth = 209.668143917888
formant [5]:
frequency = 4823.479775451361
bandwidth = 357.147764183363
frames [2]:
intensity = 0.007108941260004555
nFormants = 5
formant []:
formant [1]:
frequency = 420.7936179207871
bandwidth = 156.6697641580339
formant [2]:
frequency = 1434.5440278308877
bandwidth = 377.849704303127
formant [3]:
frequency = 2620.589627797242
bandwidth = 1336.5922989596068
formant [4]:
frequency = 3772.337062263397
bandwidth = 248.2627364453784
formant [5]:
frequency = 4748.112746186265
bandwidth = 244.23733261870277
파일 2:
frames []:
frames [1]:
intensity = 0.306356559616564358
nFormants = 5
formant []:
formant [1]:
frequency = 203.06628436252515
bandwidth = 150.21467462436982
formant [2]:
frequency = 1607.54711702621
bandwidth = 629.232413949129
formant [3]:
frequency = 3577.174907989416
bandwidth = 3535.5870557191413
formant [4]:
frequency = 4764.624274996511
bandwidth = 309.668143917888
formant [5]:
frequency = 5823.479775451361
bandwidth = 457.147764183363
frames [2]:
intensity = 0.007108941260004555
nFormants = 5
formant []:
formant [1]:
frequency = 320.7936179207871
bandwidth = 156.6697641580339
formant [2]:
frequency = 1334.5440278308877
bandwidth = 377.849704303127
formant [3]:
frequency = 2520.589627797242
bandwidth = 1336.5922989596068
formant [4]:
frequency = 4472.337062263397
bandwidth = 248.2627364453784
formant [5]:
frequency = 4648.112746186265
bandwidth = 244.23733261870277
답변1
awk oneliner (주어진 가정에 기초):
awk '{lines[FILENAME,FNR]=$0;last=FNR}END{for(i=1;i<=last;i++){mod=(i-7+19)%19;print(lines[mod>1?"file1":"file2",i])}}' file1 file2
분석은 다음과 같습니다.
{
lines[FILENAME,FNR]=$0;
last=FNR
}
위의 내용은 각 파일의 행을 저장합니다. 또한 FNR(파일 레코드 번호)을 저장하여 파일에 몇 줄이 있는지 알 수 있습니다.
END {
for(i=1;i<=last;i++) {
mod=(i-7+19)%19;
print(lines[mod>1?"file1":"file2",i])
}
}
위의 코드는 각 줄을 반복하고 값에 따라 파일 1 또는 2의 줄을 인쇄합니다 mod
. mod
7번째 라인부터 19라인마다 계산하면 매 프레임마다 포먼트[1] 데이터에 도달하게 됩니다.
답변2
이는 약간 더 높은 수준의 접근 방식입니다. 이는 스크립트 대신 쉘 스크립트를 사용합니다 awk
. 솔루션 은 awk
매우 우아합니다. 나는 이것을 대안적인 예로 제시합니다.
가정: 각 파일에는 동일한 수의 포먼트가 있으며 포먼트의 순서는 동일합니다. file1의 첫 번째 포먼트는 file2의 첫 번째 포먼트를 대체하고, 두 번째 형식은 두 번째 형식을 대체하는 식입니다. 포먼트에는 가변 개수의 라인이 포함될 수 있으며 포먼트당 라인 수는 각 파일마다 다를 수 있습니다.
스크립트는 이 csplit
명령을 사용하여 각 파일을 여러 부분으로 분할합니다. 홀수 부분에는 formant[1]
s가 포함되고 짝수 부분에는 다른 모든 내용이 포함됩니다.
두 파일을 분할한 후 file2에서 홀수 부분을 모두 제거하고 file1에서 짝수 부분을 모두 제거합니다. 그런 다음 cat
나머지 파일을 함께 결합하여 최종 출력을 생성합니다.
csplit
파일 번호를 끝에 추가하도록 출력 파일 이름 형식을 수정했기 때문에 두 원본 파일은 동일한 디렉터리로 분할되며 셸의 패턴 일치 및 정렬을 활용하여 해당 파일을 삭제하고 나머지 부분을 올바른 순서로 재조립합니다. .
#!/bin/sh
USAGE="
$0: Usage: $0 file1 file2
$0 replaces formant[1]'s in file1 with formant[1]'s from file2
$0 prints the new version of file1 on standard output
"
TMP=tmp$$
mkdir $TMP
for i in 2 1
do
csplit --quiet --prefix="$TMP/" --suffix-format="%09d-$i" "${1:?$USAGE}" \
'/formant \[[12]\]/' '{*}'
shift
done
rm $TMP/*[13579]-2
rm $TMP/*[02468]-1
cat $TMP/*
rm -r $TMP
그러면 다음과 동일한 출력이 생성됩니다.이 다른 답변
답변3
awk '
{
getline a <file2
if(prn)
print a
else
print
}
/formant \[1\]/{
prn = 1
}
/bandwidth/{
prn = 0
}
' file1
주파수를 얻기 위해 file1과 file2의 서로 다른 수의 포먼트에 대해:
awk '
BEGIN{
pattern = "formant \\[1\\]"
}
prn{
prn = 0
while($0 !~ pattern)
getline <file2
getline <file2
}
$0 ~ pattern{
prn = 1
}
1
' file1