다음 색인 파일이 있습니다
key1|1|1001
key1|1|2001
key2|2|3001
key2|2|4001
using this index file, I have to update my main file
key1|1000|2000|3000|4000
key2|1000|2000|3000|4000
The expected output should be
key1|1001|2000|3000|4000
key1|2001|2000|3000|4000
key2|1000|3001|3000|4000
key2|1000|4001|3000|4000
그런데 아래의 script.awk는 메인 파일의 키를 복사하지 않고, 해당 인덱스의 값을 계속 덮어쓰고 있습니다. 스크립트에 어떤 문제가 있나요? awk -f script.awk index.txt main.txt
#!/bin/awk
BEGIN {
FS = "|"
}
( NR == FNR ) {
lookup[toupper($1)] = $0
}
( NR > FNR ) {
key = toupper($1)
split(lookup[key], replacements, "|")
for (i = 1; i <= NF; i++)
col[i] = $i;
for (i=1; i <= NF; i=i+1){
j=replacements[i]
col[j] = replacements[i+1]
}
for (i = 1; i <= NF; i++)
printf "%s|", col[i]
}
답변1
당신은 꽤 가까워서 작업을 불필요하게 복잡하게 만들고 있습니다. 다음 스크립트를 사용해 보십시오 awk -f script.awk main.txt index.txt
(파일의 역순에 주의하세요).
#!/bin/awk
BEGIN {
FS = "|"
}
( NR == FNR ) {
lookup[toupper($1)] = $0
}
( NR > FNR ) {
key = toupper($1)
n=split(lookup[key], replacements, "|")
replacements[$2+1]=$3
for (i=1; i<n+1; i++)
printf "%s|", replacements[i]
printf "\n"
}
밝혀지다
key1|1001|2000|3000|4000|
key1|2001|2000|3000|4000|
key2|1000|3001|3000|4000|
key2|1000|4001|3000|4000|
|
파이프를 라인 끝에 유지하고 싶은지 확실하지 않지만 어쨌든 제거하는 것은 쉽지 않습니다.
접근 방식의 주요 문제점은 lookup
새 행이 key
이전 행과 동일한 값을 가질 때마다 배열을 덮어쓴다는 것입니다. 따라서 파일의 순서를 반대로 해야 합니다. 고유한 첫 번째 필드가 있는 파일을 먼저 읽어 배열 인덱스로 사용합니다.
그런데 이것은 순수한 솔루션이며 awk
다른 쉘과는 아무런 관련이 없습니다.ksh