열이 탭으로 구분된 서로 다른 형식의 두 개의 파일이 있습니다. 의 열 을 와 column1
비교 해야 합니다 . 일치하면 의 값을 의 값으로 바꿔야 합니다 . 사용해 보았으나 값을 대체할 수 없습니다. 아래 코드 조각에 대한 제안을 해주실 수 있나요?column2
file1
file2
column6
file1
column3
file2
awk
awk 'FILENAME == ARGV[1] {
m[$1,$2] = $6;
next;
}
{
if (($1,$2) in m) {
m[$6]= $3; print m[$6];
}
}' file1 file2
top few lines of file1
1201 12011 1 0 0 0 1
1202 12021 1 0 0 0 1
1203 12031 1 0 0 0 1
1204 12041 1 0 0 0 2
1207 12071 1 0 0 0 2
1209 12091 1 0 0 0 1
1210 12101 1 0 0 0 1
1212 12121 1 0 0 0 1
1213 12131 1 0 0 0 1
1214 12141 1 0 0 0 2
top few lines of file2
1201 12011 1
1202 12021 1
1203 12031 1
1204 12041 1
1206 NA 1
1207 12071 2
1208 NA 1
1209 12091 2
1210 12101 2
업데이트된 내용을 다른 파일에 쓰고 싶기 때문에 file2의 값을 file1 열에 할당하고 싶습니다.out.txt
편집하다
주석을 기반으로 다음 코드를 시도했습니다.
awk '{
if (FNR==NR) {
a[FNR]=$1;b[FNR]=$2;c[FNR]=$3}
else {
if (a[FNR] == $1 && b[FNR] ==$2) {
$6=c[FNR]} else {$6=$6};
print $0;
}
}' file2 file1
이 출력을 얻으십시오
1201 12011 1 0 0 1 1
1202 12021 1 0 0 1 1
1203 12031 1 0 0 1 1
1204 12041 1 0 0 1 2
1207 12071 1 0 0 0 2
1209 12091 1 0 0 0 1
1210 12101 1 0 0 0 1
1212 12121 1 0 0 0 1
1213 12131 1 0 0 0 1
1214 12141 1 0 0 0 2
답변1
awk -F"\t" -v OFS="\t" '{
if (FNR==NR) {
a[FNR]=$1;b[FNR]=$2;c[FNR]=$3}
else {
if (a[FNR] == $1 && b[FNR] ==$2) {
$6=c[FNR]} else {$6=$6};
print $0
}
}' file2 file1
나는 이것이 일을 끝낼 것이라고 생각합니다. 먼저, 각각 인덱스를 사용하여 file2의 첫 번째, 두 번째 및 세 번째 열을 array 에 저장합니다 a
( file2의 행에만 해당). Else (file1의 행에만 적용) 배열 sum의 값을 sum과 비교합니다. 일치하는 경우 배열의 6번째 필드를 변경합니다. 그렇지 않으면 값을 동일한 값에 다시 할당하고 구분 기호를 .b
c
FNR
FNR = NR
a
b
$1
$2
c
tab
답변2
큰 망치가 아닌 또 다른 awk
접근 방식
while read f1 f2 f3; do
sed -E -i "s/^($f1\s+$f2.*)([0-9]+)$/\1$f3/" file1;
done < file2
마지막 숫자가 정수라고 가정합니다. 그렇지 않은 경우 ([0-9])$
적절한 캡처 그룹으로 수정해야 합니다.
이는 file1에 대한 내부 수정에 의존하므로 복사본이 필요합니다.
답변3
awk 스크립트를 보면 각 입력 파일을 다르게 처리하는 올바른 아이디어가 이미 있습니다(대부분의 경우 NR == FNR
숫자 비교가 문자열 비교보다 빠르기 때문에 더 좋고 빠르게 작동하는지 확인하지만... ...수천 개의 입력이 있는 경우) 파일의 경우 이것이 중요합니다(하나 또는 두 개의 파일에 있는 입력 줄 수).
그러나 스크립트가 원하는 작업을 수행하지 못하게 하는 몇 가지 문제가 있습니다.
잘못된 순서로 파일을 읽고 있습니다. file1의 행을 출력하고 6열을 file2의 열 3으로 바꾸려고 하기 때문에 먼저 file2를 읽어 배열을 작성해야 합니다
m
(file2의 인덱스 , file2의$1,$2
값 ).$3
.수정
m[$6]
한 후 인쇄하고 있습니다. 최대 1개의 열이 인쇄됩니다.
다음과 같이 시도해 보세요.
$ awk 'NR == FNR { m[$1,$2] = $3; next }
($1,$2) in m { $6 = m[$1,$2] }
1' file2 file1
1201 12011 1 0 0 1 1
1202 12021 1 0 0 1 1
1203 12031 1 0 0 1 1
1204 12041 1 0 0 1 2
1207 12071 1 0 0 2 2
1209 12091 1 0 0 2 1
1210 12101 1 0 0 2 1
1212 12121 1 0 0 0 1
1213 12131 1 0 0 0 1
1214 12141 1 0 0 0 2
또는 NR == FNR
첫 번째 줄을 원래 FILENAME == ARGV[1]
.
각 줄 file2
(읽을 첫 번째 파일 - 명령줄의 파일 이름 인수 순서에 유의)에 대해 $3를 배열에 저장 m
하고 다음 입력 줄로 점프합니다. 열 합계는 배열에 대한 인덱스 $1
로 사용됩니다.$2
그런 다음 읽기 file1
(및 후속 입력 파일이 있는 경우) 시 배열의 인덱스인 경우 배열에 저장된 값으로 ($1,$2)
대체됩니다 .$6
m
그런 다음 수정 여부에 관계없이 현재 입력 줄을 인쇄합니다(모드 자체는 1
"현재 입력 줄 인쇄"를 의미하는 awk 관용구/단축 키입니다. "1"은 true로 평가되고 기본 작업은 "인쇄"입니다. . 그래서 사실상 "참이면 인쇄됩니다")
참고: 샘플 예상 출력을 제공하지 않았으므로 출력이 원하는 것과 일치하는지 확인할 수 없습니다. 일반적으로 OP의 샘플 출력을 파일에 저장하고 광산이 일치하는지 사용하거나 확인하는 것을 좋아 diff
합니다 cmp
. 내 awk 스크립트의 출력이 일치합니다.내 설명귀하의 질문에서 무엇을 요구하고 있습니까?