Batasi oleh ruang tetapi abaikan ruang backslash

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 []

Saya ingin mendapatkan kolom pertama di atas tetapi tangkapannya adalah, saya perlu memperlakukan \ (spasi garis miring terbalik) sebagai bagian dari kolom, jadi awk '{print $1}'harus memberi saya

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
GypsyCosmonaut
sumber
Apakah saya diperlakukan sebagai karakter pelarian atau hanya \ spesial? Misalnya, apakah a\\ bsatu atau dua bidang?
Gregory Nisbet
@GregoryNisbet yang saya masukkan \ adalah untuk karakter pelarian, bukan data sebenarnya
GypsyCosmonaut
1
Jika data Anda mengandung backslash nyata, bagaimana data itu diwakili?
Gregory Nisbet
@GregoryNisbet Pertanyaan bagus. Karena saya ganti hanya [[:space:]]dengan \[[:space:]], data asli telah \ belum tersentuh di tempat mereka. Setelah mendapatkan data asli di kolom pertama dibatasi hanya oleh spasi dan tidak \[[:space:]], saya akan mengganti \[[:space:]]dengan [[:space:]]dan saya akan kembali dengan data asli kembali yang memiliki \.
GypsyCosmonaut

Jawaban:

9

dengan gnu awk ( gawk) Anda dapat menggunakan beberapa pernyataan nol panjang seperti \<atau \>:

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

tapi sayangnya bukan yang full-blown dari perlatau pcre(misalnya. (?<!\\), (?<=\w), dll):

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

Anda dapat mengganti \ space dengan sesuatu yang lain dan kembali lagi sesudahnya.

sed 's/\\ /\\x20/g' data_file | awk '{ print $1; }' | sed 's/\\x20/\\ /g'
pLumo
sumber
Hanya dengan sed: sed / s / \\ / \\ x20 / g; s /. * //; s / \\ x20 / \\ / g 'data_file
ctac_
Atau, awk, menggunakan nilai variabel SUBSEP default \034:awk '{gsub(/\\ /,SUBSEP,$0); val=$1; gsub(SUBSEP,"\\ ",val); print val}' file
glenn jackman
5

Dengan GNU grepatau yang kompatibel:

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

Atau dengan ERE:

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

Itu memperlakukan \sebagai operator mengutip, untuk spasi putih sebagai pembatas, tetapi juga untuk dirinya sendiri. Artinya, pada foo\\ barinput, ia kembali foo\\.

Stéphane Chazelas
sumber
4

Hanya dengan sed:

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

Atau lebih pendek:

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

Ini (([^\]*\\ ){1,})?[^ ]*cocok:

  • [^\]*\\: apa pun yang bukan back-slash yang diakhiri dengan back-slash diikuti oleh spasi (perhatikan bahwa \di dalam kelas karakter tidak diperlukan untuk melarikan diri, tetapi di luar tidak).
  • ([^\]*\\ ){1,}: cocok di atas dengan satu atau lebih kali kejadian.
  • (([^\]*\\ ){1,})?: ini opsional saat menggunakan (...)?; kita bisa menggunakan ([^\]*\\ ){0,}juga atau ([^\]*\\ )*.
  • ((([^\]*\\ ){1,})?[^ ]*): pertandingan di atas yang bersifat opsional diikuti oleh apa pun yang bukan spasi dan tahan sebagai pertandingan grup dengan \1sebagai referensi belakang.
  • ((([^\]*\\ ){1,})?[^ ]*).*: cocok di atas (...)dan yang lainnya .*.

maka bagian pengganti hanya cetak \1yang merupakan output:

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
αғsнιη
sumber