Làm thế nào để khớp chuỗi chính xác bằng cách sử dụng `sed`? Nhưng không phải là một phần của nó.?


8

Tôi có một tệp đầu vào FILE1.TXT như dưới đây.


11 id1  
12  
13 AGE = 20  
14 NAME = NAME1  
15  
16 id2  
17  
18 AGE = 30  
19 NAME = NAME2  
.  
.  
.  
110 idXYZ  
111  
112 AGE = AGEXYZ  
113 NAME = NAMEXYZ  
114  
115 idZZZ  
116

Tôi muốn tìm kiếm tất cả các trường thuộc về một Id cụ thể và nhận giá trị cho NAME

Tôi quản lý để lặp qua từng Id và hình thành lệnh dưới đây cho mỗi Id theo yêu cầu.

sed -n '/11/,/14/p' FILE1.TXT | grep NAME | awk -F "= " '{print $2}'

Vấn đề ở đây là, tôi nhận được đầu ra NAME1 , ngoài ra, tôi cũng nhận được NAMEXYZ .

Nên thay đổi cái gì để tôi chỉ nhận được NAME1 chứ không phải NAMEXYZ ?

Như một giải pháp thay thế, các lệnh dưới đây hoạt động.

sed -n '/11/,/14/p' FILE1.TXT | grep NAME | awk -F "= " '{print $2}'|head -1

Có bất kỳ 'chuyển đổi' hoặc tôi đang thiếu một cái gì đó?

Câu trả lời:


3

Nếu bạn biết số dòng bạn muốn tìm kiếm (như Q của bạn gợi ý), hãy thắt chặt biểu thức chính quy để bạn không khớp với các dòng không mong muốn.

Ví dụ: thay đổi:

sed -n '/11/,/14/p' | grep NAME | awk -F "= " '{print $2}'

đến

sed -n '/^11 /,/^14 /p' | grep NAME | awk -F "= " '{print $2}'

Các ^sẽ phù hợp với đầu dòng và một không gian sau khi đảm bảo rằng số số dòng cụ thể sẽ được xuất hiện, và bạn sẽ không xử lý khối không mong muốn.


Điều đó sẽ giúp. Nhưng, làm thế nào tôi có thể phù hợp ^(random no of spaces)11?
Vinay

1
@VinayChalluru sử dụngsed -n '/^\s*11 /,/^\s*14 /p'
casey

1
nó có thể là tay ngắn sử dụng sed -n '/^11 /,/^14 /p' | awk '/NAME/{print $NF}' bạn đã thử điều này?
Rahul Patil

@RahulPatil Vâng, nó hoạt động.
Vinay

6

Sử dụng ranh giới từ:

grep '\bNAME1\b'

sẽ phù hợp NAME1và không NAME1XYZhoặc XYZNAME1.

Tương tự

sed -n '/11\b/,/14\b/p'

sẽ không khớp dòng chứa 111142.


EDIT: Có vẻ như các số trong tệp đầu vào thực sự là số dòng. Nếu đó là trường hợp, bạn có thể chỉ cần nói:

sed '11,14!d'

để có được các dòng mong muốn.


Chỉ có một NAMEgiữa dòng 11 và 14. Vậy, tại sao lại sednhìn vào 111114? Làm thế nào để làm cho nó không nhìn vào giữa 111114?
Vinay

@VinayChalluru Xem câu trả lời ở trên để biết cách bạn có thể sửa đổi sedbiểu thức.
devnull

Điều này trả lời câu hỏi của tôi, tôi đoán. Hãy để tôi thử và cho bạn biết.
Vinay

cho ranh giới từ, grepvới -wcờ? phải không
Rahul Patil

1
@RahulPatil Yup, ví dụ trên -wsẽ tương đương. Ví seddụ, -wlà hơi khác nhau.
devnull

4

Bạn có thể sử dụng AWK

awk 'NR>=13 && NR<=17 && /NAME/{print $NF}' infile

Điều này sẽ tìm các dòng từ 13 đến 17 sau đó tìm kiếm Tên và nếu khớp thì nó sẽ in từ cuối cùng từ Name = LastWord


Khi tôi cố gắng thực hiện việc này, tôi gặp lỗi khi nói rằng số dòng đầu vào phải nhỏ hơn 199.
Vinay

@VinayChalluru bạn có thể chỉ cho tôi đầu ra bằng lệnh, sử dụng paste.ubfox.com
Rahul Patil

Lời xin lỗi. Tôi đã thêm một $trước NRvà điều đó gây ra lỗi.
Vinay

@VinayChalluru Không sao đâu. Thật tốt khi bạn đã thử / kiểm tra từng ans và học một cái gì đó mới ..: D
Rahul Patil

Chính xác. Còn rất nhiều điều phía trước. :-)
Vinay

4

Bạn không cần bất kỳ công cụ nào khác cho việc này, sedsẽ dễ dàng xử lý toàn bộ.

sed -nr '/11/,/14/{s/^.*NAME =\s*(\S*).*$/\1/p}' <$infile

Điều đó sẽ chỉ cung cấp cho bạn chuỗi ký tự không phải khoảng trắng đầu tiên theo cụm từ "NAME =" cho mỗi dòng mà cụm từ đó được tìm thấy giữa các dòng 11 và 14 của bất kỳ tệp đầu vào nào sedđược cung cấp.


3

sed không phải là công cụ phù hợp cho công việc này. Sử dụng awk nơi bạn có thể chỉ định id bạn đang tìm và in TÊN tiếp theo xuất hiện.

awk -v id="id2" '
    $NF == id {have_id = 1} 
    have_id && $0 ~ /NAME/ {print $NF; exit}
' filename

Bạn có thể giải thích dòng hai và ba của lệnh awk của bạn?
erik

0

phiên bản chung không dựa trên số dòng nhưng tham chiếu id

sed -n '1h;1!H;
$ {
  x
  s/.*/&\^J/
: clean
#  put your ID pattern here in place of id9
  s/.*\(id9 *\n.*\)id[0-9]\{1,\} *\n.*/\1/
  t clean
  s/.*NAME = \([^[:cntrl:]]*\)\n.*/\1/
  p
  }' YourFile
  1. tải toàn bộ tập tin
  2. phần sạch không phải là một phần của nhóm id (đệ quy)
  3. chỉ cần lấy TÊN giá trị nội dung trong nhóm
  4. in kết quả

0

bạn có thể in những dòng có chứa mẫu phù hợp bằng cách sử dụng sed như sau:

sed -n '/pattern/p'  Filename
  • -n- các tùy chọn này vô hiệu hóa chức năng in tự động này và sed chỉ tạo đầu ra khi được thông báo rõ ràng thông qua plệnh.

  • p - in

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.