Làm thế nào tôi có thể hợp nhất các mẫu trong một dòng?


10

Tôi đang thực hiện grep và sed và tôi nhận được 2 dòng tệp mà tôi quan tâm. Làm cách nào tôi có thể nhận được các dòng này trong một dòng kết thúc bằng ký tự dòng mới?
Bây giờ tôi đang nhận được:

pattern1  
pattern2  

tôi muốn có được pattern1 pattern2 \n


1
Bạn có thể chia sẻ thêm dữ liệu mẫu?
slm

Sử dụng printf %s\\n pattern1 pattern2 | sed '$!N;s/\n/ /'
Valentin Bajrami

Dán là công cụ cho công việc, nếu bạn có ý định hợp nhất nhiều dòng đầu ra thành một.
slm

công cụ cụ thể nào? Làm thế nào để bạn có kế hoạch để làm điều này?
Braiam

Câu trả lời:


7

paste:

{...pipeline...} | paste -d " " - -

Điều đó nói rằng: "đọc một dòng từ stdin (đầu tiên -), đọc một dòng khác từ stdin (thứ hai -), sau đó nối chúng với một khoảng trắng"


một kỹ thuật cụ thể bash:

$ x=$(grep -o pattern. test.txt)
$ echo "$x"
pattern1
pattern2
$ mapfile -t <<< "$x"
$ echo "${MAPFILE[*]}"
pattern1 pattern2

ref: http://www.gnu.org/software/bash/manual/bashref.html#index-mapfile


- -gì Là lệnh như vậy?
Jim

@Jim - vâng đúng vậy. Những người đang nói pastelàm thế nào bạn muốn nó xử lý đầu vào. 2 tại một thời điểm. Thêm nhiều hơn để làm 3 tại thời điểm. seq 10 | paste -d " " - - .
slm

6

Tôi sẽ đặt ba phiên bản phương pháp khác nhau liên tiếp

AWK

printf %s\\n pattern1 pattern2 | awk -vRS="\n" -vORS=" " '1; END {print RS}'

SED

printf %s\\n pattern1 pattern2 | sed '$!N;s/\n/ /'

TR

printf %s\\n pattern1 pattern2 | tr '\n' ' '; echo

Và còn nhiều hơn thế nữa.


Các trgiải pháp sẽ nuốt xuống dòng kết thúc, vì vậy bạn có thể muốn thêm ; echomột điều đó
glenn Jackman

@glennjackman ah đúng rồi! Cảm ơn đã gợi ý. Bạn được tự do sửa đổi câu trả lời mặc dù. Tôi đã bỏ lỡ một chút!
Valentin Bajrami

2

bạn có thể làm điều đó bằng cách sử dụng shell script hoặc trong dòng lệnh, chỉ cần đặt đầu ra của lệnh vào một biến sau echođó:

# x=$(grep -e "pattern1\|pattern2" test)
# printf '%s\n' "$x"
pattern1 pattern2

không được trích dẫn, biến cũng có thể được mở rộng tên tệp, vì vậy nếu bạn có bất kỳ ký tự toàn cầu nào (như *hoặc ?) trong kết quả, các giá trị có thể thay đổi.
glenn jackman

@glennjackman, cảm ơn vì đã đề cập đến vấn đề này, làm thế nào chúng ta có thể khắc phục điều này?
Nidal

@Networker bằng cách không sử dụng backticks mà $()thay vào đó .. và sử dụng printfprintf '%s\n' "$x"
Valentin Bajrami

Tôi hy vọng rằng printf '%s\n' "$x"sẽ KHÔNG xóa dòng mới "nội bộ".
glenn jackman

2

Với sed, bạn có thể làm điều này:

<your previous commands> | sed '{N; s/\n/ /}'
  • N;nói sedđể thêm dòng tiếp theo vào không gian mẫu, vì vậy bây giờ sedđang làm việc với cả hai dòng.
  • s/\n/ / thay thế ký tự dòng mới bằng một khoảng trắng, "hợp nhất" hai dòng lại với nhau.

2

Một cách đơn giản, đầu ra ống để xargs:

$ echo -e 'a\nb' | xargs
a b

Điều này chỉ hoạt động với ouput nhỏ, bởi vì nó bị giới hạn bởi các ký tự tối đa trên mỗi dòng lệnh. Giá trị lớn nhất phụ thuộc vào hệ thống, bạn có thể nhận giá trị này bằng cách sử dụng getconf ARG_MAX.


1
( set -f; IFS='
'; printf '%s %s\n' $(grepcmd <input)
) >output

IFS sẽ rất vui khi ăn nó nếu bạn muốn.


-1

bọc sed / grep của bạn trong backticks

khi lệnh ban đầu của bạn là:

grep -i 'foo' mylog.log | sed 's/bar/baz/gi'

lệnh mới của bạn sẽ là:

`grep -i 'foo' mylog.log | sed 's/bar/baz/gi'`

Không có khoảng trắng ở giữa các dòng, nhưng bạn luôn có thể giải quyết trên một ống sed khác:

 | sed 's/$/ /'

1
À, không. Điều đó sẽ thực hiện đầu ra của lệnh sed.
glenn jackman
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.