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
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
Câu trả lời:
Với sed:
ls | grep txt | sed 's/.*/prefix&suffix/'
sedlà một superset của grep: ls | sed -n '/txt/s/.*/prefix&suffix/p'hoặcls | sed -n 's/.*txt.*/prefix&suffix/p'
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 $_.
“và chỉ sử dụng em.
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 1và -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ữ ".".*thing.*thay vì chỉthing-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, bashcó compgenđó, 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.
sedvà findcá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`/%"
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?