Các giá trị được phân tách bằng tab trong awk


90

Làm cách nào để chọn cột đầu tiên từ chuỗi được phân tách TAB?

# echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F'\t' '{print $1}'

Ở trên sẽ trả về toàn bộ dòng chứ không chỉ "LOAD_SETTLED" như mong đợi.

Cập nhật:

Tôi cần thay đổi cột thứ ba trong các giá trị được phân tách bằng tab. Sau đây không hoạt động.

echo $line | awk 'BEGIN { -v var="$mycol_new" FS = "[ \t]+" } ; { print $1 $2 var $4 $5 $6 $7 $8 $9 }' >> /pdump/temp.txt

Tuy nhiên, điều này hoạt động như mong đợi nếu dấu phân tách là dấu phẩy thay vì tab.

echo $line | awk -v var="$mycol_new" -F'\t' '{print $1 "," $2 "," var "," $4 "," $5 "," $6 "," $7 "," $8 "," $9 "}' >> /pdump/temp.txt

4
awk 'BEGIN {FS = "[\ t] +"}; {print $ 1} '# đây là những gì tôi đang tìm kiếm. Tìm kiếm trên google của tôi có chính xác không? :)
shantanuo

3
Nhờ nhận xét này, tôi đã khám phá ra: awk 'BEGIN {FS="\t"}; {print $1,FS,$2,FS,$3}' myFile.txtin các giá trị được phân cách bằng tab của ba cột đầu tiên.
Wok

6
Hoặc có lẽ đơn giảnawk 'BEGIN {OFS="\t"}; {print $1,$2,$3}'
Josiah Yoder

3
Cả GNU và BSD awk đều hỗ trợ -vđể thiết lập các biến. Thật tệ khi sử dụng BEGIN {FS="\t"}bên trong một chương trình nội tuyến và bất kỳ đóng góp mã nguồn mở nào mà bạn cố gắng thực hiện như vậy đều có thể bị phản đối. Chỉ làm điều đó nếu bạn đang viết một tệp chương trình . Ngoài ra, nó không được khuyến khích sử dụng -Fthay -v FS=vì vì cái sau nói rõ rằng chỉ FSđang được thiết lập và không OFS. Sự nhầm lẫn về điểm cuối cùng là nguyên nhân gây ra bài đăng này ngay từ đầu. Đó là lý do tại sao "phong cách tốt" là quan trọng.
Bruno Bronosky

1
Xin vui lòng, không ai, không bao giờ, nên làm những gì @Wok đã chứng minh. Bạn không liệt kê Dấu phân cách trường [Đầu vào] trong Đầu ra của mình. Bạn chỉ định Dấu phân tách trường đầu ra thông qua OFSbiến.
Bruno Bronosky

Câu trả lời:


141

Bạn cần đặt OFSbiến (dấu phân tách trường đầu ra) thành một tab:

echo "$line" | 
awk -v var="$mycol_new" -F $'\t' 'BEGIN {OFS = FS} {$3 = var; print}'

(đảm bảo rằng bạn trích dẫn $linebiến trong câu lệnh echo)


6
Mục đích của $ trong $ '\ t' là gì?
Amr Mostafa

10
Trả lời câu hỏi của riêng tôi từ Hướng dẫn Viết mã Bash Nâng cao : Cấu trúc mở rộng chuỗi được trích dẫn $ '...' là một cơ chế sử dụng các giá trị bát phân hoặc hex ..., ví dụ: quote = $ '\ 042'.
Amr Mostafa

5
@AmrMostafa, quá xấu mà dẫn có một lời giải thích sai lạc hàng đầu một khi nghĩ rằng bạn làm không phải là $trong $'\t'là không cần thiết. Wiki của Greg thì tốt hơn: "Trong số này, $'...'là cách phổ biến nhất và hoạt động giống như các dấu ngoặc kép ngoại trừ các kết hợp thoát ra sau dấu gạch chéo ngược được mở rộng theo quy định của tiêu chuẩn ANSI C".
Cristian Ciupitu,

9
Trong nhận thức muộn màng, điều $'\t'này là không cần thiết. awk hiểu chuỗi "\t"là một ký tự tab
glenn jackman

5
Các cộng tác viên nguồn mở, tôi xin bạn, vui lòng không gửi những thứ như thế awk -F $'\t' 'BEGIN {OFS = FS} …'. Điều đó nên được awk -v FS='\t' -v OFS='\t' '…'. Nó có vẻ có vẻ khó hiểu, nhưng không nhất quán sẽ làm tăng khả năng một người đóng góp sau này đưa ra lỗi vì họ hiểu sai mã của bạn.
Bruno Bronosky

21

Đảm bảo rằng chúng thực sự là các tab! Trong bash, bạn có thể chèn một tab bằng cách sử dụngC-v TAB

$ echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -F$'\t' '{print $1}'
LOAD_SETTLED


9

Tôi sử dụng FSOFScác biến để thao tác các tệp vùng BIND được phân cách bằng tab. Đây là một trong những tập lệnh của tôi https://gist.github.com/RichardBronosky/abe1652c2d5c78c35b92ad02bdf0d0af#file-dns_update-sh-L36-L39

Thịt của nó là:

awk -v FS='\t' -v OFS='\t' \
    -v record_type=$record_type \
    -v hostname=$hostname \
    -v ip_address=$ip_address '
$1==hostname && $3==record_type {$4=ip_address}
{print}
' $zone_file > $temp

Đây là một cách rõ ràng và dễ đọc để làm điều này.


5
echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk -v var="test" 'BEGIN { FS = "[ \t]+" } ; { print $1 "\t" var "\t" $3 }'

0

Điều này có nên không hoạt động?

echo "LOAD_SETTLED    LOAD_INIT       2011-01-13 03:50:01" | awk '{print $1}'
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.