열 교체 및 간격 유지

열 교체 및 간격 유지

후속작입니다유닉스: 한 파일의 전체 열을 다른 파일의 단일 값으로 바꿉니다.

파일(file1)의 열을 다른 파일(file2)의 특정 값으로 바꾸려고 합니다.

file1의 구조는 다음과 같습니다.

HETATM    8  P   FAD B 600      98.424  46.244  76.016  1.00 18.65
HETATM    9  O1P FAD B 600      98.634  44.801  75.700  1.00 17.69 O  
HETATM   10  O2P FAD B 600      98.010  46.640  77.387  1.00 15.59 O  
HETATM   11 H5B1 FAD B 600      96.970  48.950  72.795  1.00 -1.00 H  

이 구조를 반드시 유지해야 합니다.

file2의 구조는 다음과 같습니다.

1 27, -81.883, 4.0
5 48, -67.737, 20.0
1 55, -72.923, 4.0
4 27, -62.64, 16.0

나는 awk가 "오작동"하고 내 pdb 파일의 형식을 잃어버렸다는 것을 알았습니다. 이는 대신 다음을 의미합니다.

HETATM    1  PA  FAD B 600      95.987  47.188  74.293  1.00 -73.248

알겠어요

HETATM 1 PA FAD B 600 95.887 47.194 74.387 1.00 -73.248 

나는 시도했다:

file1="./Min1_1.traj_COP1A_.27.pdb"
file2="./COP1A_report1"
value="$(awk -F, 'NR==1{print $2;exit}' $file2)"
#option 1: replaces the column I want but messes up the format
awk -F ' ' '{$11 = v} 1' v="$value" $file1 >TEST1
#option 2: keeps the format but adds the value at the end only
awk -F ' ', '{$2 = v} 1' v="$value" $file1 >TEST2
awk -F, '{$11 = v} 1' v="$value" $file1 >TEST3

나는 이것이 pdb 파일의 모든 열에 동일한 구분 기호가 없고 awk가 내가 원하는 방식으로 처리하지 않기 때문이라고 추측합니다.

이 문제를 해결하기 위해 awk를 "길들이는" 방법이나 사용할 다른 명령에 대한 아이디어가 있습니까?

답변1

공백이 아닌 정규식을 사용 [^[:blank:]]하고 첫 번째 11일치 항목을 바꿉니다.

awk '{print gensub (/[^[:blank:]]+/, v, 11)}' v="$value" infile

sed같은

sed "s/[^[:blank:]]\{1,\}/${value}/11" infile

또 다른 방법은, 파일에 고정 길이 필드가 있고 각 필드의 "위치"를 알고 있는 경우(예: 예제 파일에 공백만 있다고 가정하면 11번째 필드는 4자를 차지하고 각 줄은 57번째에서 60번째가 됩니다)

awk '{print substr($0,1,56) v substr($0,61)}' v=$value file

또는

sed -E "s/^(.{56}).{4}(.*)$/\1${value}\2/" infile

답변2

GAWK 4를 사용하면 문자열(또는 전체 줄)을 명시적으로 분할하고 출력을 위해 분할 결과(필드 및 구분 기호)를 반복하여 필드 구분 기호를 보존할 수 있습니다.

이 예에서는 FPAT(필드 구조를 지정하는 정규식)을 사용하지만 (필드 구분 기호를 지정하거나 단일 공백을 포함하는 정규식 )을 대신 patsplit()사용할 수도 있습니다 .FS[ \t\n]+split()

gawk "v=$value" '{n = patsplit($0, arr, FPAT, seps); arr[11] = v; for (i = 0; i <= n; i++) {printf "%s%s", a[i], seps[i]}; print ""}'

이는 a[0]항상 비어 있고, seps[0]선행 구분 문자를 포함하며, seps[n]입력 줄 끝에 구분 문자(공백)가 됩니다.

다음은 더 읽기 쉬운 형식의 한 줄의 코드입니다.

gawk "v=$value" '
    {
        n = patsplit($0, arr, FPAT, seps); 
        arr[11] = v; 
        for (i = 0; i <= n; i++) {
            printf "%s%s", a[i], seps[i]
        }; 
        print ""
    }'

답변3

sed귀하의 작업에 사용하고 싶습니다 :

file1="./Min1_1.traj_COP1A_.27.pdb"
file2="./COP1A_report1"
IFS=',' read -r a value b <"$file2"
#for second field:
sed "s/.[0-9]\b/$value/" "$file1" > TEST1
#for 11th field:
sed "s/\S.\.[0-9]\{2\}\b/$value/" "$file1" > TEST1

관련 정보