Phân định theo không gian nhưng bỏ qua dấu gạch chéo ngược


8
5678 []
testing,\ group []
[testing []
ip\ 5.6.7.8 []
launch-wizard-1 0.0.0.0/0
456dlkjfa []
1.2.3.4 []
test 1.2.3.4/32 4.3.2.0/23 4.3.2.0/23
default 4.3.2.0/23 4.3.2.0/23
launch-wizard-2 0.0.0.0/0
launch-wizard-3 0.0.0.0/0
2.3.4.5/32 []

Tôi muốn lấy cột đầu tiên ở trên nhưng điều thú vị là, tôi cần coi \ (dấu gạch chéo ngược) là một phần của cột, vì vậy awk '{print $1}'nên cung cấp cho tôi

5678
testing,\ group
[testing
ip\ 5.6.7.8
launch-wizard-1
456dlkjfa
1.2.3.4
test
default
launch-wizard-2
launch-wizard-3
2.3.4.5/32

Là \ luôn luôn được coi là một nhân vật thoát hoặc chỉ là \ đặc biệt? Chẳng hạn, a\\ bmột hay hai lĩnh vực?
Gregory Nisbet

@GregoryNisbet Tôi đã đặt \ là cho ký tự thoát, không phải dữ liệu thực
GypsyCosmonaut

1
Nếu dữ liệu của bạn có chứa dấu gạch chéo ngược thực sự, nó sẽ được biểu diễn như thế nào?
Gregory Nisbet

@GregoryNisbet Câu hỏi hay. Bởi vì tôi chỉ thay thế [[:space:]]bằng \[[:space:]], dữ liệu gốc đã được xử lý ở vị trí của chúng. Sau khi nhận được dữ liệu gốc trong cột đầu tiên được phân cách bằng dấu cách và không \[[:space:]], tôi sẽ thay thế \[[:space:]]bằng [[:space:]]và tôi sẽ được để lại dữ liệu gốc có \.
GypsyCosmonaut

Câu trả lời:


9

với gnu awk ( gawk) bạn có thể sử dụng một số xác nhận có độ dài bằng không như \<hoặc \>:

$ echo 'a\ b c' | gawk 'BEGIN{FS="\\> +"} {print $1}'
a\ b

nhưng tiếc là không phải là những full-blown từ perlhoặc pcre(ví dụ. (?<!\\), (?<=\w), vv):

$ echo 'a\ b, c' | perl -nle '@a=split /(?<!\\)\s+/, $_; print $a[0]'
a\ b,

5

Bạn có thể thay thế \ khoảng trống bằng thứ khác và quay lại sau đó.

sed 's/\\ /\\x20/g' data_file | awk '{ print $1; }' | sed 's/\\x20/\\ /g'

Chỉ với sed: sed 's / \\ / \\ x20 / g; s /. * //; s / \\ x20 / \\ / g' data_file
ctac_

Hoặc, awk, sử dụng giá trị biến SUBSEP mặc định của \034:awk '{gsub(/\\ /,SUBSEP,$0); val=$1; gsub(SUBSEP,"\\ ",val); print val}' file
glenn jackman

5

Với GNU grephoặc tương thích:

grep -Po '^(\\.|\S)*'

Hoặc với ERE:

grep -Eo '^(\\.|[^\[:space:]])*'

Điều đó coi \như là một toán tử trích dẫn, cho khoảng trắng như là một dấu phân cách, nhưng cũng cho chính nó. Đó là, trên foo\\ barđầu vào, nó trả về foo\\.


4

Chỉ với sed:

sed -r 's/^((([^\]*\\ ){1,})?[^ ]*).*/\1/' infile

Hoặc ngắn hơn:

sed -r 's/^(([^\]*\\ )*[^ ]*).*/\1/' infile

Trận (([^\]*\\ ){1,})?[^ ]*đấu này :

  • [^\]*\\: bất cứ điều gì không phải là dấu gạch chéo ngược kết thúc bằng dấu gạch chéo ngược theo sau là khoảng trắng (lưu ý rằng \bên trong lớp ký tự không bắt buộc phải thoát, nhưng bên ngoài thì không).
  • ([^\]*\\ ){1,}: khớp ở trên với một hoặc nhiều lần xuất hiện.
  • (([^\]*\\ ){1,})?: đây là tùy chọn khi sử dụng (...)?; chúng ta có thể sử dụng ([^\]*\\ ){0,}thay thế là tốt hoặc ([^\]*\\ )*.
  • ((([^\]*\\ ){1,})?[^ ]*): khớp trên đây là tùy chọn theo sau bởi bất kỳ thứ gì không phải là khoảng trắng và giữ dưới dạng khớp nhóm với \1tham chiếu ngược.
  • ((([^\]*\\ ){1,})?[^ ]*).*: phù hợp ở trên (...)và bất cứ điều gì khác .*.

Sau đó, phần thay thế chỉ cần in \1phần đầu ra:

5678
testing,\ group
[testing
ip\ 5.6.7.8
launch-wizard-1
456dlkjfa
1.2.3.4
test
default
launch-wizard-2
launch-wizard-3
2.3.4.5/32
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.