awk를 사용하여 파일을 변경하는 방법은 무엇입니까? ("sed -i"와 동일)

awk를 사용하여 파일을 변경하는 방법은 무엇입니까? ("sed -i"와 동일)

awk스크립트 가 있습니다 new.awk.

BEGIN { FS = OFS = "," }

NR == 1 {
    for (i = 1; i <= NF; i++)
        f[$i] = i
}

NR > 1 {
    begSecs = mktime(gensub(/[":-]/, " ", "g", $(f["DateTime"])))
    endSecs = begSecs + $(f["TotalDuration"])
    $(f["CallEndTime"]) = strftime("%Y-%m-%d %H:%M:%S", endSecs)
}

{ print }

나는 이것을 쉘에서 부른다.

awk new.awk sample.csv

...하지만 터미널에서 변경 사항을 볼 수 있습니다. 를 사용할 때처럼 파일의 내용을 어떻게 변경할 수 있나요 sed -i?

답변1

GNU awk(Linux 시스템에서 공통) 버전 4.1.0부터 명령줄에 "소스 라이브러리"를 포함할 수 있습니다 awk(-i--includegawk의 -i 옵션이나 @include 지시문을 안전하게 사용하는 방법은 무엇입니까?그리고 이와 관련된 보안 문제에 대한 아래의 Stéphane의 의견). GNU와 함께 배포되는 소스 라이브러리 중 하나 awk는 다음과 같습니다 inplace.

$ cat file
hello
there
$ awk -i inplace '/hello/ { print "oh,", $0 }' file
$ cat file
oh, hello

보시다시피 이로 인해 코드 출력이 awk입력 파일을 대체합니다. there프로그램은 해당 라인을 출력하지 않으므로 유지되지 않습니다.

awk파일의 스크립트 의 경우 다음과 같이 사용할 수 있습니다

awk -i inplace -f script.awk datafile

awk변수가 INPLACE_SUFFIX문자열로 설정되면 라이브러리는 파일 이름 접미사를 사용하여 원본 파일을 백업합니다.

awk -i inplace -v INPLACE_SUFFIX=.bak -f script.awk datafile

입력 파일이 여러 개인 경우 각 파일을 개별적으로 내부에서 편집할 수 있습니다. 그러나 inplace=0해당 파일 앞의 명령줄에서 다음을 사용하여 파일(또는 파일 그룹)의 내부 편집을 끌 수 있습니다 .

awk -i inplace -f script.awk file1 file2 inplace=0 file3 inplace=1 file4

위 명령에서는 file3내부 편집이 수행되지 않습니다.


개별 파일을 보다 쉽게 ​​"내부 편집"하려면 다음을 사용하세요.

tmpfile=$(mktemp)
cp file "$tmpfile" &&
awk '...some program here...' "$tmpfile" >file
rm "$tmpfile"

입력 파일을 임시 위치에 복사한 다음 awk원래 파일 이름으로 리디렉션하는 동안 임시 파일에 코드를 적용합니다.

이 순서대로 작업을 수행하면( awk원본 파일이 아닌 임시 파일에서 실행) 원본 파일의 파일 메타데이터(권한 및 소유권)가 수정되지 않습니다.

답변2

이 시도.

awk  new.awk sample.csv > tmp.csv && mv -f tmp.csv sample.csv
  • 출력을 임시 파일로 리디렉션합니다.
  • 그런 다음 임시 파일의 내용을 원본 파일로 이동합니다.

관련 정보