Không. ?? * có nghĩa là gì trong lệnh shell?


22

Lệnh sau sẽ tartất cả các tệp và thư mục "chấm":

tar -zcvf dotfiles.tar.gz .??*

Tôi quen thuộc với các biểu thức thông thường , nhưng tôi không hiểu cách diễn giải .??*. Tôi đã thực hiện ls .??*tree .??*xem xét các tập tin được liệt kê. Tại sao biểu thức chính quy này bao gồm tất cả các tệp trong các thư mục bắt đầu bằng .ví dụ?


Câu trả lời:


32

Globs không phải là biểu thức thông thường. Nói chung, shell sẽ cố gắng diễn giải bất cứ điều gì bạn gõ trên dòng lệnh mà bạn không trích dẫn dưới dạng toàn cầu. Shell không bắt buộc phải hỗ trợ các biểu thức chính quy (mặc dù trong thực tế, nhiều trong số các fancier hiện đại hơn làm, ví dụ =~toán tử khớp regex trong bash [[cấu trúc).

.??*một quả địa cầu. Nó khớp với bất kỳ tên tệp nào bắt đầu bằng dấu chấm ., theo sau là hai ký tự bất kỳ (không nhất thiết phải giống nhau) ??, theo sau là biểu thức chính quy tương đương [^/]*, tức là 0 hoặc nhiều ký tự không có /.

Để biết chi tiết đầy đủ về mở rộng tên đường dẫn shell (tên đầy đủ của "globalbing"), hãy xem thông số POSIX .


10
Điểm bổ sung: đây là một nỗ lực để viết một quả cầu khớp với tất cả các dotfiles trong một thư mục ngoại trừ các mục đặc biệt ...thông thường không muốn làm gì với nó. Nó không hoàn toàn đúng; nó không nhận bất cứ thứ gì có tên ' .X' trong đó X là một số ký tự khác với dấu chấm. Tôi không nghĩ có thể viết một quả cầu duy nhất khớp với mọi dotfile ngoại trừ ..., nhưng bạn có thể làm điều đó với hai: tar zcvf dotfiles.tar.gz .[!.] .??*ví dụ.
zwol

@Zack: Cảm ơn đã làm rõ. Tôi đã đăng một bình luận về điều đó, nhưng sau đó đã xóa nó. ls .?trả về giống như ls .., điều đó có nghĩa là không có mục nào khác trong thư mục khớp với mẫu .?. Tôi đã làm .[^.]cho tất cả .?các tập tin khác hơn ...
SabreWolfy

2
@SabreWolfy Nếu bạn đọc kỹ thông số POSIX, đó thực sự là một sự khác biệt quan trọng giữa các khối và regex: trong biểu thức ngoặc, [^abc]trong cú pháp regex có nghĩa giống như [!abc]trong cú pháp toàn cầu (nghĩa ^là được thay thế bằng !các khối). Sử dụng [^abc]cú pháp kiểu trong toàn cầu không dễ mang theo vì POSIX không chỉ định nghĩa của nó, vì vậy một số shell diễn giải nó bằng ngữ nghĩa giống như regex trong khi những cái khác coi ^như chỉ là một ký tự.
jw013

1
@ jw013: Cảm ơn các chi tiết. Tôi phải nhớ rằng toàn cầu! =
Regapi

1
Nó chỉ xảy ra với tôi .[!.]có thể được để lại dưới dạng chữ trên tardòng lệnh trong trường hợp phổ biến khi không có tệp nào khớp với mẫu đó. Một số shell cho phép bạn kiểm soát hành vi đó, ví dụ như với bash, shopt -s nullglobsẽ khiến nó biến mất khỏi dòng lệnh nếu nó không khớp với bất cứ thứ gì, nhưng đó không phải là một tính năng phổ quát.
zwol

8

.??*tự đại diện ( không phải là biểu thức chính quy, mặc dù trông như vậy) chuyển thành tên tệp bắt đầu bằng dấu chấm ( .), theo sau là hai ký tự đơn ( ??) và sau đó là bất kỳ số nào (không hoặc nhiều hơn) của các ký tự khác ( *).

Có lẽ trang này trên Wildcards in Filenames sẽ hữu ích.


-1

Để thêm vào các câu trả lời khác, một câu ?sẽ dịch sang một tên tệp ký tự duy nhất và ??sẽ khớp với tên tệp chỉ có hai ký tự, v.v.

[root@mercy testdir_2]# ls
ion  it  r
[root@mercy  testdir_2]# ls ?
r
[root@mercy  testdir_2]# ls ??
it
[root@mercy 1 testdir_2]# ls ???
ion
[root@mercy  testdir_2]#

Downvoter, bạn có thể bình luận? Sẽ rất vui khi được sửa chữa, nếu tôi sai.
Sree

Câu trả lời của bạn không trả lời đầy đủ câu hỏi.
SabreWolfy
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.