Bash를 사용하여 여러 텍스트 파일의 특정 특정 줄에서 특정 문자열을 단일 파일로 연결합니다.

Bash를 사용하여 여러 텍스트 파일의 특정 특정 줄에서 특정 문자열을 단일 파일로 연결합니다.

다음 형식의 *.txt라는 이름의 텍스트 파일이 약 100개 있습니다.

=========================================================
 rho_center   e_center    Mass      Mass_0      R_e
 1.0000e-03 1.1236e-03 1.5379e+00 1.6522e+00 1.0734e+01
     J         T/W       Omega   Omega_Kepler axes_ratio
 0.0000e+00 0.0000e+00 0.0000e+00 3.5265e-02 1.0000e+00
    J/M^2
 0.0000e+00
=========================================================
yy| rhoc  =   1.00000000e-03 ;
yy| rp_re =   1.00000000e+00 ;
yy| A_diff=   1.00000000e+00 ;
yy| Re    =   1.07336268e+01 ;
yy| M0    =   1.65219709e+00 ;
yy| M     =   1.53786062e+00 ;
yy| W     =   2.10814073e-01 ;
yy| T     =   0.00000000e+00 ;
yy| J     =   0.00000000e+00 ;
yy| beta  =   0.00000000e+00 ;
yy| M_R   =   1.43275023e-01 ;
  | === periods in msecs ==========
yy| Pa    =              inf ;
yy| Pe    =              inf ;
yy| td    =   8.46677695e-01 ;
yy| PK    =   8.77582921e-01 ;
yy| MDIV = 301 ; SDIV = 601;

다음과 같이 텍스트 파일에서 rhoc과 M의 값을 연결하고 싶습니다.

rhoc M
0.001 1.537
...    ...
0.004 2.328

저는 bash를 처음 접했고 awk를 사용하여 이 작업을 시도했지만 실패했습니다. 이를 위해 bash 스크립트를 어떻게 작성할 수 있습니까?

답변1

예를 들어, 파일당 / gawk하나만 있다고 가정하면 다음과 같습니다.rhocM

gawk '
  BEGIN {print "rhoc M"}
  BEGINFILE {delete field}
  $3 == "=" {field[$2] = $4}
  ENDFILE {
    if (("rhoc" in field) && ("M" in field))
      print field["rhoc"], field["M"]
  }' ./*.txt

파일 이름을 기준으로 사전순으로 파일을 처리합니다. 사용하는 경우 순서가 숫자가 되도록 로 바꾸 zsh십시오 ( 그래서./*.txt./*.txt(n)file2.txt앞으로 file10.txt예를 들어).

답변2

Gawk가 아닌 용도로 사용하려면(Linux(mawk) 및 FreeBSD에서 테스트됨) 다음을 시도해 보세요.

LC_ALL=C awk -vHD="rhoc M" '
BEGIN           {for (MX=m=split(HD, IX); m; m--) FLDS[IX[m]]
                 print HD
                }
FNR == 1        {CNT++
                }               
$2 in FLDS      {OUT[$2, CNT] = $4+0
                }
END             {for (i=1; i<=CNT; i++) {for(j=1; j<=MX; j++) printf "%.6g%s", OUT[IX[j],i], (j==MX?ORS:OFS)}
                }
'  *.txt
rhoc M
0.001 1.53786

HD 변수를 간단히 사전 확장하여 데이터 추출을 확장할 수 있습니다. 입력 파일 수를 세고, 각 파일에 필요한 데이터를 OUT 배열로 수집하고, 파일이 발견된 순서대로 END 섹션의 모든 데이터를 인쇄합니다.

답변3

sed:

sed -n '/rhoc/{s/^yy| rhoc *= *\([0-9.e+-]*\) *;/\1/;h;};/ M /{s/^yy| M *= *\([0-9.e+-]*\) *;/\1/;x;G;s/\n/ /p}' sample

여러 줄 방식으로:

sed -n '
    /rhoc/{
        s/^yy| rhoc *= *\([0-9.e+-]*\) *;/\1/
        h
    }
    / M /{
        s/^yy| M *= *\([0-9.e+-]*\) *;/\1/
        x;G;s/\n/ /p
    }
' sample

관련 정보