Chuỗi tiền tố và hậu tố cho mỗi dòng đầu ra từ lệnh


16

Tôi đã gặp phải một vấn đề khi cố gắng viết một kịch bản Bash. Khi grepđầu ra, nó trả về (thường) nhiều dòng. Tôi muốn tiền tố và hậu tố một chuỗi cho mỗi dòng đầu ra.

Tôi cũng muốn lưu ý rằng tôi đang lstham gia grep, như:

ls | grep

2
Bạn không nên phân tích cú pháp ls- đó là juju xấu. Ngoài ra, nó có phải là grep? Và bạn có thể đưa ra một số ví dụ đầu ra?
Sobrique

1
Bạn muốn tập lệnh của mình làm gì nếu tên tệp chứa dòng mới?
Tai Viinikka

Câu trả lời:


26

Với sed:

ls | grep txt | sed 's/.*/prefix&suffix/'

3
Hoặc, sedlà một superset của grep: ls | sed -n '/txt/s/.*/prefix&suffix/p'hoặcls | sed -n 's/.*txt.*/prefix&suffix/p'
Stéphane Chazelas

@ StéphaneChazelas: Cảm ơn bạn đã gợi ý này.
Cyrus

5

Với sed:

ls | grep pattern | sed -e 's/^/prefix/' -e 's/$/suffix/'

Nhưng lưu ý, điều này gặp phải vấn đề với tên tệp với nguồn cấp dữ liệu và tất cả các vấn đề về phân tích cú pháp lsthường là một ý tưởng tồi.

Với perl

perl -e 'print "prefix".$_."suffix\n" for grep { m/somepattern/} glob "*"'

Lưu ý - perl grepcó thể lấy một mẫu - giống như greplệnh, nhưng bạn cũng có thể thực hiện những việc như áp dụng kiểm tra tệp.

Ví dụ

grep {-d} glob "*" #filters directories.
grep { (stat)[9] > time() - 60 } glob "*" #reads file mtime and compares. 

Trong grepiterator mặc định $_được đặt thành giá trị phần tử hiện tại, do đó bạn có thể áp dụng sed/ grepkiểu regex hoặc thực hiện nhiều tác vụ khác nhau dựa trên $_.


Làm thế nào tôi có thể bao gồm một biến làm hậu tố / tiền tố trong ví dụ đầu tiên của bạn bằng cách sử dụng seded?
SpecialBomb

Thay đổi dấu ngoặc kép và chỉ sử dụng em.
Sobrique

2

Trong trường hợp này GNU findcho phép bạn thực hiện tất cả những việc này trong một lần, loại bỏ các đường ống và phân tích cú pháp có thể gây rắc rối ls:

find . -maxdepth 1 -name '[^.]*' \
  -regextype posix-extended -regex "MYPATTERN" \
  -printf 'SOMEPREFIX %f SOMESUFFIX\n'

(tất nhiên findkhông phải là một cách tốt để tự ý sửa đổi đầu ra của các lệnh khác!)

Một số lưu ý:

  • -maxdepth 1-name [^.]*làm cho khớp tên hoạt động giống như một đơn giản ls(hoặc ls .). Bạn có thể sử dụng bất kỳ kiểu toàn cầu nào, nhưng lưu ý rằng "*" sẽ khớp với dấu "." trong một cái tên không giống như bashvậy, [^.]*có nghĩa là bất cứ thứ gì không có chữ "."
  • MYPATTERN là một POSIX ERE thích hợp (loại mặc định là Emacs, xem tại đây ), nhưng nó phải khớp với toàn bộ tên tệp để sử dụng một cái gì đó như .*thing.*thay vì chỉthing
  • bạn có thể chỉ cần sử dụng một trong -name/ -regexthay vì cả hai (ví dụ: -regex "[^.]. MYPATTERN. "
  • -printfhỗ trợ rất nhiều thứ , %nlà tên tập tin hoặc thư mục chưa được cung cấp

(điều này có thể phụ thuộc vào phiên bản của finddù, kiểm tra "TIÊU CHUẨN sự phù hợp" của người đàn ông trang của bạn)

Là một thay thế có thể không có chương trình bên ngoài cần thiết, bashcompgenđó, trong số những thứ khác, mở rộng những đống, tương đương với lskhông có tùy chọn:

compgen -P "someprefix>" -S "<somesuffix" -G "pattern"

Điều này xử lý tên tệp với khoảng trắng, bao gồm cả dòng mới. compgen -G "*"nên cung cấp cùng một đầu ra như một đồng bằng ls(nhưng lưu ý rằng đó ls *là một điều hoàn toàn khác). Bạn vẫn sẽ cần grep, và điều này có thể hoặc không thể giải quyết vấn đề, nhưng nó đáng được đề cập.


0

sedfindcác giải pháp bị thách thức nếu tiền tố / hậu tố của bạn bao gồm các ký tự khóa regex hoặc nếu muốn chuyển một biến môi trường (thay vì giá trị ngay lập tức), xargs+ echocó thể phù hợp hơn ở đây.

Với biến môi trường:

ls | grep p | xargs -I % sh -c "echo $PATH/%"

Với một nội tuyến:

ls | grep p | xargs -I % sh -c "echo `pwd`/%"
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.