Làm cách nào để liệt kê một tên tệp cho mỗi dòng đầu ra trong Linux?


229

Tôi đang sử dụng ls -alệnh để lấy tên tệp trong một thư mục, nhưng đầu ra nằm trong một dòng.

Như thế này:

.  ..  .bash_history  .ssh  updater_error_log.txt

Tôi cần một giải pháp thay thế tích hợp để có được tên tệp, mỗi tên trên một dòng mới, như thế này:

.  
..  
.bash_history  
.ssh  
updater_error_log.txt

3
ls được dự định để hiển thị một danh sách cho tiêu dùng của con người. Nếu bạn đang sử dụng ls cho bất kỳ mục đích nào khác (như giả sử, để lấy danh sách các tệp trong tập lệnh để lặp lại), bạn chắc chắn sử dụng sai công cụ.
Juliano

2
@juliano - Nó thực sự được sử dụng bởi một kịch bản python. Tại sao bạn gọi nó là một công cụ sai?
fixxxer

1
@fixxer Khoảnh khắc bạn lschuyển sang python, lssẽ xuất một tệp trên mỗi dòng như tôi đã giải thích trong câu trả lời của mình.
Peter G.

6
@fixxxer: Vậy thì bạn thực sự đang sử dụng sai. Nó định dạng danh sách cho đầu ra trong thiết bị đầu cuối người dùng. Nó có thể thay thế các ký tự đặc biệt trong tên tệp, nó có thể bỏ qua các ký tự có ý nghĩa đặc biệt, v.v ... Nói cách khác, ls định dạng một danh sách cho người dùng. Bạn muốn tên tập tin chưa được định dạng. Bất kỳ lý do đặc biệt nào mà bạn không sử dụng mô-đun 'toàn cầu' của python? docs.python.org/library/glob.html Ngoài ra còn có 'fnmatch', 'dircache' và những người khác.
Juliano

@fixxer Bạn đã thực sự thực hiện lsđể xuất ra pythonvà quan sát đầu ra một dòng trong python chưa?
Peter G.

Câu trả lời:


430

Sử dụng -1tùy chọn (lưu ý đây là chữ số "một", không phải chữ thường "L"), như thế này:

ls -1a

Tuy nhiên, trước tiên, hãy chắc chắn rằng sự lshỗ trợ của bạn -1. GNU coreutils (được cài đặt trên các hệ thống Linux tiêu chuẩn) và Solaris làm; nhưng nếu nghi ngờ, sử dụng man lshoặc ls --helphoặc kiểm tra tài liệu. Ví dụ:

$ man ls
...
       -1     list one file per line.  Avoid '\n' with -q or -b

2
1 Tôi không biết về -1 (có -l (ell không một)) Nó cho thấy trong người đàn ông trang nhưng tôi đã đọc nó như một ell trong suốt thời gian :)
slashmais

@slashmais - Ah, điểm tốt - dễ nhầm. Tôi đã làm rõ trong câu trả lời.
Bert F

1
@dty: đối với GNU, bạn nhận được tài liệu này ở ls --helpđầu ra ... luôn được cài đặt ;-)
Tony Delroy

3
Tìm kiếm trên Google linux ls one file per linevà đây là bài viết hàng đầu. Không thể tin được câu trả lời được chọn dài dòng như thế nào hoặc câu trả lời này có ít phiếu hơn so với câu trả lời cho con mèo. ls -1ftw.
crantok

3
lsmặc định cho -1hành vi khi đầu ra không được kết nối với thiết bị đầu cuối.
codeforester

132

Có, bạn có thể dễ dàng tạo lsmột tên tệp trên mỗi dòng:

ls -a | cat

Giải thích: Lệnh lscảm nhận nếu đầu ra là tới một thiết bị đầu cuối hoặc tập tin hoặc đường ống và điều chỉnh cho phù hợp.

Vì vậy, nếu bạn ống ls -ađể trăn, nó sẽ hoạt động mà không có biện pháp đặc biệt.


2
Wow, điều này thật tuyệt vời. Lợi thế so với câu trả lời được chấp nhận - câu trả lời này thực sự hoạt động trên Android / adb shell - nơi lschỉ là một phiên bản rút gọn nên không hỗ trợ-1
mkilmanas

Làm thế nào bạn sẽ tránh ..."tập tin" hiển thị trong đầu ra mặc dù?
matanster

@matanster: Nó phụ thuộc, bạn có muốn xem các tập tin dấu chấm không? Nếu không, chỉ cần bỏ tùy chọn -a.
Peter G.

29

Ls được thiết kế cho tiêu dùng của con người và bạn không nên phân tích đầu ra của nó .

Trong các kịch bản shell, có một vài trường hợp trong đó phân tích cú pháp đầu ra của ls không hoạt động là cách đơn giản nhất để đạt được hiệu quả mong muốn. Vì ls có thể thu thập các ký tự không phải ASCII và các ký tự điều khiển trong các tên tệp, nên các trường hợp này là một tập hợp con của những ký tự không yêu cầu lấy tên tệp từ đó ls.

Trong python, hoàn toàn không có lý do để gọi ls. Python có tất cả các lschức năng tích hợp sẵn. Sử dụng os.listdirđể liệt kê nội dung của một thư mục và os.stathoặc osđể có được siêu dữ liệu tệp. Các chức năng khác trong các osmô-đun có khả năng cũng liên quan đến vấn đề của bạn.


Nếu bạn đang truy cập các tệp từ xa qua ssh, một cách hợp lý để liệt kê tên tệp là thông qua sftp:

echo ls -1 | sftp remote-site:dir

Điều này in một tên tệp trên mỗi dòng và không giống như lstiện ích,sftp không mang các ký tự không thể in được. Bạn vẫn sẽ không thể liệt kê một cách đáng tin cậy các thư mục chứa tên tệp chứa dòng mới, nhưng điều đó hiếm khi được thực hiện (hãy nhớ đây là vấn đề bảo mật tiềm năng, không phải là vấn đề về khả năng sử dụng).

Trong python (hãy cẩn thận rằng các siêu ký tự shell phải được thoát trong remote_dir):

command_line = "echo ls -1 | sftp " + remote_site + ":" + remote_dir
remote_files = os.popen(command_line).read().split("\n")

Đối với các tương tác phức tạp hơn, hãy tìm chế độ hàng loạt của sftp trong tài liệu.

Trên một số hệ thống (Linux, Mac OS X, có thể là một số hợp nhất khác, nhưng chắc chắn không phải Windows), một cách tiếp cận khác là gắn hệ thống tệp từ xa thông qua ssh với sshfs , sau đó hoạt động cục bộ.


Tôi được kết nối qua SSH với máy từ xa. Tôi không tìm thấy cách nào để thực thi một hàm python như os.listdir trên máy từ xa trong một dòng duy nhất. Do đó, câu hỏi này. Tôi không muốn viết một tập lệnh cho việc liệt kê các tập tin đơn giản. Có cách nào khác xung quanh vấn đề này?
fixxxer

@fixxxer: ssh thay đổi tình hình, đó là loại điều bạn nên đề cập trong câu hỏi ban đầu của mình! Tôi nghĩ rằng sftp là thích hợp cho trường hợp sử dụng của bạn.
Gilles 'SO- ngừng trở nên xấu xa

Tôi xin lỗi vì sự nhầm lẫn. Có cách nào để tôi có thể chèn mật khẩu vào "lệnh_line" không?
fixxxer

@fixxxer: Tôi không biết, các tác giả của ssh cau mày với mật khẩu được lưu trữ trong văn bản thuần túy và có xu hướng không làm điều này dễ dàng. Bạn thực sự nên thiết lập xác thực dựa trên khóa (có rất nhiều hướng dẫn trên web và câu hỏi trên superuser.com về điều này).
Gilles 'SO- ngừng trở thành ác quỷ'

11

bạn có thể dùng ls -1

ls -l cũng sẽ làm việc


Câu trả lời hàng đầu đã đề cập đến những điều chính xác mà bạn nói. câu hỏi cụ thể nói ls -lkhông nên được sử dụng.
DevX

2

Dễ dàng, miễn là tên tệp của bạn không bao gồm các dòng mới:

find . -maxdepth 1

Nếu bạn đang chuyển lệnh này sang một lệnh khác, có lẽ bạn nên tách tên tệp của mình bằng byte rỗng, thay vì dòng mới, vì byte null không thể xuất hiện trong tên tệp (nhưng dòng mới có thể):

find . -maxdepth 1 -print0

In trên thiết bị đầu cuối có thể sẽ hiển thị dưới dạng một dòng, vì các byte null thường không được in. Một số chương trình có thể cần một lựa chọn cụ thể để xử lý null-phân đầu vào, ví dụ như sort's -z. Kịch bản của riêng bạn tương tự sẽ cần phải tính đến điều này.

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.