Làm cách nào để thay đổi một tập tin tại chỗ bằng awk? (như với sed sed -i mệnh)


11

Tôi có một awkkịch bản , 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 }

Tôi đang gọi nó trong vỏ

awk new.awk sample.csv

... nhưng tôi có thể thấy những thay đổi trong thiết bị đầu cuối. Làm cách nào để thay đổi tại chỗ trong tệp, như khi sử dụng sed -i?

Câu trả lời:


16

GNU awk(thường được tìm thấy trên các hệ thống Linux), kể từ phiên bản 4.1.0, có thể bao gồm một " awkthư viện nguồn" có -ihoặc --includetrên dòng lệnh. Một trong những thư viện nguồn được phân phối với GNU awklà một trong những thư viện được gọi là inplace:

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

Như bạn có thể thấy, điều này làm cho đầu ra của awkmã thay thế tệp đầu vào. Dòng nói therekhông được giữ vì nó không được chương trình xuất ra.

Với một awktập lệnh trong một tập tin, bạn sẽ sử dụng nó như

awk -i inplace -f script.awk datafile

Nếu awkbiến INPLACE_SUFFIXđược đặt thành một chuỗi, thì thư viện sẽ tạo một bản sao lưu của tệp gốc với đó là hậu tố tên tệp.

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

Nếu bạn có một vài tệp đầu vào, thì mỗi tệp sẽ được chỉnh sửa tại chỗ. Nhưng bạn có thể tắt chỉnh sửa tại chỗ cho một tệp (hoặc một bộ tệp) bằng cách sử dụng inplace=0trên dòng lệnh trước tệp đó:

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

Trong lệnh trên, file3sẽ không được chỉnh sửa tại chỗ.


Để "chỉnh sửa tại chỗ" di động hơn cho một tệp, hãy sử dụng

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

Điều này sẽ sao chép tệp đầu vào vào một vị trí tạm thời, sau đó áp dụng awkmã trên tệp tạm thời trong khi chuyển hướng đến tên tệp gốc.

Thực hiện các thao tác theo thứ tự này (chạy awktrên tệp tạm thời, không phải trên tệp gốc) đảm bảo rằng siêu dữ liệu tệp (quyền và quyền sở hữu) của tệp gốc không bị sửa đổi.


4

Thử cái này.

awk  new.awk sample.csv > tmp.csv && mv -f tmp.csv sample.csv
  • chuyển hướng đầu ra đến một tập tin tạm thời.
  • sau đó di chuyển nội dung của tệp tạm thời sang tệp gốc.

1
Nếu bạn nhìn vào mã nguồn awk inplace thì đây chính xác là những gì nó làm: tạo một tệp tạm thời, chuyển hướng thiết bị xuất chuẩn ở đó và cuối cùng đổi tên nó thành tệp đầu vào.
chx
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.