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 ls
tham 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 ls
tham gia grep
, như:
ls | grep
Câu trả lời:
Với sed:
ls | grep txt | sed 's/.*/prefix&suffix/'
sed
là 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 ls
thườ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 grep
có thể lấy một mẫu - giống như grep
lệ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 grep
iterator 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
/ grep
kiể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 find
cho 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 find
khô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
và -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ư bash
vậy, [^.]*
có nghĩa là bất cứ thứ gì không có chữ ".".*thing.*
thay vì chỉthing
-name
/ -regex
thay vì cả hai (ví dụ: -regex "[^.]. MYPATTERN. "-printf
hỗ trợ rất nhiều thứ , %n
là 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
find
dù, 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, bash
có compgen
đó, trong số những thứ khác, mở rộng những đống, tương đương với ls
khô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.
sed
và find
cá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
+ echo
có 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?