Câu trả lời:
Lệnh :
ls -ld .?*
Sẽ chỉ liệt kê các tập tin ẩn.
Giải thích:
-l use a long listing format
-d, --directory
list directory entries instead of contents, and do not derefer‐
ence symbolic links
.?* will only state hidden files
.
và ..
ra khỏi trận đấu. Tuy nhiên, nó cũng sẽ loại trừ các tên tập tin ẩn một ký tự (hoàn toàn hợp pháp) .a
, .1
v.v. Có lẽ một quả cầu được mở rộng tốt hơn sẽ có .!(|.)
nghĩa là dấu chấm theo nghĩa đen được theo sau bởi bất cứ thứ gì ngoại trừ không có gì hoặc một dấu chấm (đơn) khác tức làls -d .!(|.)
ls -d .!(|.)
Liệu chính xác những gì OP đang tìm kiếm.
!(pattern-list)
, pattern-list
là một danh sách một hoặc nhiều mẫu được phân tách bằng một |
, nhưng điều khó hiểu đối với tôi là bạn không có bất kỳ mẫu nào ở bên trái |
. Bạn có thể vui lòng giải thích cú pháp đó cho tôi?
.
không được theo sau (không có gì hoặc .
), ngoại trừ .
chính nó và ..
.
Nếu bạn chỉ muốn các tệp trong thư mục hiện tại của bạn (không có đệ quy), bạn có thể làm
echo .[^.]*
Điều đó sẽ in tên của tất cả các tệp có tên bắt đầu bằng a .
và được theo sau bởi một hoặc nhiều ký tự không dấu chấm. Lưu ý rằng điều này sẽ thất bại đối với các tệp có tên bắt đầu bằng các dấu chấm liên tiếp, vì vậy, ví dụ ....foo
sẽ không được hiển thị.
Bạn cũng có thể sử dụng find
:
find -mindepth 1 -prune -name '.*'
Việc -mindepth
đảm bảo chúng tôi không khớp .
và -prune
phương tiện find
sẽ không rơi vào các thư mục con.
Sử dụng find
và awk
,
find . -type f | awk -F"/" '$NF ~ /^\..*$/ {print $NF}'
Giải trình:
find . -type f
-> Liệt kê tất cả các tệp trong thư mục hiện tại cùng với đường dẫn như,
./foo.html
./bar.html
./.foo1
awk -F"/" '$NF ~ /^\..*$/ {print $NF}'
/
khi phân tách trường awk kiểm tra trường cuối cùng có nhìn thấy dấu chấm hay không. Nếu nó bắt đầu bằng một dấu chấm, thì nó sẽ in trường cuối cùng của dòng tương ứng đó.
find -type f
. Bạn không cần phải thiết lập đường dẫn tìm kiếm hay -name "*"
.
find
thường là một lựa chọn tốt hơn cho các tìm kiếm phức tạp hơn là sử dụng tên toàn cầu.
find . -mindepth 1 -maxdepth 1 -name '.*'
hoặc là
find . -mindepth 1 -maxdepth 1 -name '.*' -o -name '*~'
find .
tìm kiếm thư mục hiện tại
-mindepth 1
không bao gồm và .. từ danh sách
-maxdepth 1
giới hạn tìm kiếm trong thư mục hiện tại
-name '.*'
tìm tên tập tin bắt đầu bằng dấu chấm
-o
hoặc là
-name '*~'
tìm tên tệp kết thúc bằng dấu ngã (thông thường, đây là các tệp sao lưu từ các chương trình chỉnh sửa văn bản)
Tuy nhiên, điều này và tất cả các câu trả lời khác bỏ lỡ các tệp trong .hidden
tệp của thư mục hiện tại . Nếu bạn đang viết một tập lệnh, thì những dòng này sẽ đọc .hidden
tệp và hiển thị tên tệp của những tập lệnh tồn tại.
if [[ -f .hidden]] # if '.hidden' exists and is a file
then
while read filename # read file name from line
do
if [[ -e "$filename" ]] # if the read file name exists
then
echo "$filename" # print it
fi
done < .hidden # read from .hidden file
fi
.hidden
tập tin? Tại sao sẽ có một tệp được gọi .hidden
có chứa tên tệp? Dù sao, nếu có một lý do tại sao bạn sẽ làm một cái gì đó phức tạp khi tất cả những gì bạn cần sẽ là cat .hidden
? find
Lệnh của bạn là chính xác (ish) nhưng -name '*~'
không liên quan. Các tệp kết thúc bằng dấu ngã là các tệp sao lưu nhưng không bị ẩn theo bất kỳ cách nào.
.hidden
Tệp này dành cho các tệp và thư mục bạn muốn ẩn khi bạn không thể thay đổi tên tệp / thư mục để bắt đầu bằng dấu chấm. Đối với các tệp kết thúc bằng dấu ngã, nó phụ thuộc vào hệ thống. ls -B
sẽ bỏ qua các tệp như vậy, như hầu hết các nhà thám hiểm tệp GUI.
cat .hidden
có thể hiển thị các tệp không còn tồn tại nếu các tệp đó bị xóa hoặc di chuyển kể từ khi được thêm vào .hidden
tệp.
Tôi nghĩ rằng bạn có thể làm điều đó với lệnh sau.
ls -a | grep "^\." | grep -v "^\.$" | grep -v "^\..$"
ls -a
lệnh bạn đã nhập, hiển thị tất cả các tệp và thư mục trong thư mục làm việc hiện tại.
grep "^\."
lệnh tôi đã nối, bộ lọc đầu ra chỉ hiển thị các tệp bị ẩn (Tên bắt đầu bằng "."
).
grep -v "^\.$" | grep -v "^\..$"
lệnh tôi đã nối, bộ lọc đầu ra để loại trừ., .. (Chúng là thư mục hiện tại và thư mục mẹ).
Nếu một số tên tệp có thể có nhiều dòng "\n"
, ví dụ trên có thể không chính xác.
Vì vậy, tôi đề nghị lệnh sau để giải quyết vấn đề.
find -maxdepth 1 -name ".[!.]*"
ls
nên phân tích đầu ra của .
Những gì bạn có thể đã làm, is ls .?*
Hoặc ls .!(|)
điều đó sẽ cho bạn thấy tất cả mọi thứ trong tập tin / thư mục ẩn hiện tại trên đầu trang và các tập tin / thư mục khác bên dưới
ví dụ: từ thiết bị đầu cuối của tôi
$ ls .?*
.bash_history .dmrc .macromedia .weather
.bash_logout .gksu.lock .profile .wgetrc
.bash_profile .bashrc.save .ICEauthority .toprc .Xauthority
.bashrc .lastdir .viminfo .xsession-errors
.bashrc~ .dircolors .lynxrc .vimrc .xsession-errors.old
..:
Baron
.adobe:
Flash_Player
.aptitude:
cache config
.cache:
compizconfig-1 rhythmbox
dconf shotwell
Bây giờ chú ý trong các kết quả ở trên, nó hiển thị cho bạn mọi tệp / thư mục con với thư mục con và bất kỳ tệp ẩn nào ngay bên dưới.
[1:0:248][ebaron@37signals:pts/4][~/Desktop]
$ ls .!(|)
.bash_aliases .bashrc1 .bashrc1~
..:
askapache-bash-profile.txt examples.desktop Public top-1m.csv
backups Firefox_wallpaper.png PycharmProjects top-1m.csv.zip
Desktop java_error_in_PYCHARM_17581.log Shotwell Import Log.txt topsites.txt
Documents Music Templates Videos
Downloads Pictures texput.log vmware
Xin lỗi, tôi không thể bình luận. để giải thích sự khác biệt ở đây giữa ls .?*
và @ trả lời cioby23 ls -d .[!.]* .??*
Và tại sao nó thực sự được in các tập tin ẩn hai lần là vì nghĩa đen bạn đang yêu cầu hai lần .??*
, .?*
, .[!.]*
họ là những điều tương tự, vì vậy thêm bất kỳ trong số họ với các nhân vật khác nhau lệnh sẽ in hai lần.
Tất cả các câu trả lời cho đến nay đều dựa trên thực tế là các tệp (hoặc thư mục) mà tên bắt đầu bằng dấu chấm bị "ẩn". Tôi đã đưa ra một giải pháp khác, có thể không hiệu quả, nhưng giải pháp này không giả sử bất cứ điều gì về tên của các tệp ẩn và do đó tránh được việc liệt kê ..
trong kết quả (như câu trả lời hiện được chấp nhận).
Lệnh đầy đủ là:
ls -d $(echo -e "$(\ls)\n$(\ls -A)" | sort | uniq -u)
Giải trình
Những gì nó làm là liệt kê tất cả các tệp (và thư mục) hai lần,
echo -e "$(\ls)\n$(\ls -A)"
nhưng chỉ hiển thị các tập tin ẩn một lần -A
.
Sau đó, danh sách được sắp xếp | sort
làm cho các tệp thông thường (không bị chặn) xuất hiện hai lần và cạnh nhau.
Sau đó, xóa tất cả các dòng xuất hiện nhiều lần | uniq -u
, chỉ để lại các dòng duy nhất.
Cuối cùng sử dụng ls
lại để liệt kê tất cả các tệp có tùy chọn tùy chỉnh của người dùng và không liệt kê nội dung của các thư mục trong danh sách -d
.
EDIT (Hạn chế):
Như muru đã chỉ ra, giải pháp này sẽ không hoạt động chính xác nếu có các tệp có tên như escaped\ncharacter.txt
vì echo -e
sẽ chia tên tệp thành hai dòng. Nó cũng sẽ không hoạt động như mong đợi nếu có hai tệp ẩn có cùng tên gần như ngoại trừ một ký tự đặc biệt, chẳng hạn như .foo[tab].txt
và .foo[new-line].txt
cả hai tệp được in .foo?.txt
và sẽ bị loại bỏ bởiuniq -u
.
như là ký tự đầu tiên.
..
, nhưng tôi tự hỏi nó hoạt động tốt như thế nào với tên tệp chứa các ký tự đặc biệt.
echo -e
sẽ giải thích. Ngoài ra: ls
sẽ không mang tên tệp để hai tên tệp khác nhau được hiển thị giống nhau (ví dụ: trong một số phiên bản ls
sẽ sử dụng ?
cho các ký tự đặc biệt, vì vậy .foo\tbar
( \t
=> tab) và .foo\nbar
( \n
=> dòng mới) sẽ hiển thị dưới dạng foo?bar
).
Ngoài ra, bạn cũng có thể sử dụng echo .*
ví dụ
user@linux:~$ echo .*
. .. .bash_aliases .bash_history .bash_logout .bashrc
user@linux:~$
Nếu bạn thích nó ở định dạng danh sách dài, chỉ cần chuyển đổi khoảng trắng sang một dòng mới.
user@linux:~$ echo .* | tr ' ' '\n'
.
..
.bash_aliases
.bash_history
.bash_logout
.bashrc
user@linux:~$
Với bash, việc đặt GLOBIGNORE
biến đặc biệt là một số giá trị không trống là đủ để làm cho nó bỏ qua .
và ..
khi mở rộng các khối. Từ các tài liệu Bash :
Biến
GLOBIGNORE
shell có thể được sử dụng để hạn chế tập hợp tên tệp khớp với mẫu. NếuGLOBIGNORE
được đặt, mỗi tên tệp phù hợp cũng khớp với một trong các mẫu trongGLOBIGNORE
sẽ bị xóa khỏi danh sách khớp. Nếunocaseglob
tùy chọn được đặt, việc khớp với các mẫu trongGLOBIGNORE
được thực hiện mà không liên quan đến trường hợp. Tên tệp.
và..
luôn bị bỏ qua khiGLOBIGNORE
được đặt và không null. Tuy nhiên, cài đặt thànhGLOBIGNORE
giá trị khác null có tác dụng cho phép tùy chọn shell dotglob, vì vậy tất cả các tên tệp khác bắt đầu bằng‘.
'sẽ khớp.
Nếu chúng ta đặt nó thành .:..
, cả hai .
và ..
sẽ bị bỏ qua. Vì đặt nó thành bất cứ thứ gì khác null cũng sẽ có hành vi này, chúng tôi cũng có thể đặt nó thành.
Vì thế:
GLOBIGNORE=.
ls -d .*
ls -ld .*
ls -ald .*