Làm cách nào để chỉ xuất tên tệp (có dấu cách) trong ls -Al?


78

Tôi chỉ nên lặp lại tên của các tệp hoặc thư mục với cấu trúc này:

ls -Al | while read string
do
...
done

ls -Al đầu ra:

drwxr-xr-x  12 s162103  studs         12 march 28 12:49 personal domain
drwxr-xr-x   2 s162103  studs          3 march 28 22:32 public_html
drwxr-xr-x   7 s162103  studs          8 march 28 13:59 WebApplication1

Ví dụ: nếu tôi thử:

ls -Al | while read string
do
echo "$string" | awk '{print $9}
done

sau đó chỉ xuất ra các tập tin và thư mục không có khoảng trắng. Nếu tệp hoặc thư mục có khoảng trắng như "miền cá nhân" thì đó sẽ chỉ là từ "cá nhân".

Tôi cần giải pháp rất đơn giản. Có lẽ có giải pháp tốt hơn awk.


2
Tại sao không chỉ ls -Al *' '*? lsĐầu ra của phân tích cú pháp không bao giờ dẫn đến bất cứ điều gì tốt.
manatwork

1
Nếu bạn cần một cái gì đó sẽ hoạt động trong bất kỳ * nix nào, hãy thử tránh sử dụng ls -Al | while. Một cách đơn giản và đáng tin cậy hơn là for string in *; do echo "$string"; done.
Forcefsck

chỉ cần với công trình này..okay, không đơn giản, bất kỳ giải pháp nào!
Alex Zern

1
Tại sao bạn cần ls ? Phân tích cú pháp lsvà "hoạt động trong tất cả * nix và sẽ không phá vỡ nếu có chuyện gì xảy ra" không kết hợp tốt với nhau.
terdon

Câu trả lời:


97

Bạn thực sự không nên phân tích đầu ra củals . Nếu đây là bài tập về nhà và bạn được yêu cầu, giáo sư của bạn không biết họ đang nói về cái gì. Tại sao bạn không làm điều gì đó như thế này:

Tốt...

find ./  -printf "%f\n"

hoặc là

for n in *; do printf '%s\n' "$n"; done

...Những người xấu...

Nếu bạn thực sự muốn sử dụng ls, bạn có thể làm cho nó mạnh mẽ hơn một chút bằng cách làm một cái gì đó như thế này:

ls -lA | awk -F':[0-9]* ' '/:/{print $2}'

... và xấu xí

Nếu bạn khăng khăng làm sai, nguy hiểm và chỉ cần sử dụng một whilevòng lặp, hãy làm điều này:

ls -Al | while IFS= read -r string; do echo "$string" | 
    awk -F':[0-9]* ' '/:/{print $2}'; done

Nghiêm túc mà nói, đừng.


drwx------ 2 s162103 studs 3 oct. 9 2012 .ssh drwxr-xr-x 3 s162103 studs 6 oct. 25 09:02 .subversion drwxrwxrwt 3 s162103 studs 3 nov. 15 2012 .TempoItemsđôi khi tôi đã hẹn hò mà không có thời gian, chỉ có năm và gawk trở lại trống rỗng
Alex Zern

1
@AlexZern Chà, đó là một trong những lý do bạn không phân tích đầu ra ls.
terdon

2
@AlexZern tại sao bạn vẫn cần -lchuyển đổi? Nếu tất cả những gì bạn muốn là tên tập tin, chỉ cần chạy ls -A. Sử dụng -lchỉ làm cho cuộc sống của bạn khó khăn hơn vì bây giờ bạn phải phân tích đầu ra.
terdon

bởi vì tôi cần thêm thông tin như quyền truy cập, ngày tháng, chủ sở hữu, v.v. Và tôi đã viết một kịch bản lớn, hoạt động tốt, ngoại trừ tên tệp in và thư mục có dấu cách.
Alex Zern

3
Được rồi Những gì chúng ta có ở đây là một vấn đề XY . lskhông chỉ là cách tốt nhất để có được những gì bạn cần. Tại sao bạn không đăng câu hỏi mới giải thích thông tin bạn muốn thu thập và chúng tôi có thể đề xuất các cách thực hiện. Ngoài ra, bạn có thể sử dụng tập lệnh của mình và sử dụng một trong các đề xuất ở trên để chỉ in tên. Nhưng nghiêm túc, đừng phân tích ls, chỉ cần cho chúng tôi biết chính xác những gì bạn đang cố gắng làm trong một câu hỏi mới.
terdon

74

Có một số lý do mà ls -A1* sẽ không làm việc?

Ví dụ:

$ touch file1 file2 file\ with\ spaces
$ ls -Al
total 0
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file1
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file2
-rw-r--r-- 1 bahamat bahamat 0 Mar 30 22:31 file with spaces
$ ls -A1
file1
file2
file with spaces
$

* Lưu ý: đó là chữ in hoa A và số một.


4
-1 là thiên tài. Tôi không biết rằng đã có sẵn. (Tôi biết tôi biết. RTFM)
Bộ giải mã lười biếng

chỉ hoạt động cho thư mục hiện tại nếu bạn muốn liệt kê tên tệp từ thư mục khác nói ~ / dự án thì bạn sẽ nhận được đường dẫn đầy đủ thay vì tên tệp
thecotne

@thecotne trên Mac 10.9.5, nó chỉ liệt kê tên tệp. Bạn đang sử dụng hệ điều hành nào?
AJP

tôi đang chạy này ls ~ / dự án / * -A1 cao cả dự án cho ls ~ / dự án -A1 tôi không nhận được chỉ tên.
thecotne

3
@TheLazyCoder sẽ không mong đợi để đọc hướng dẫn.
c24w

41

Tôi tự hỏi tại sao không ai đề cập đến lệnh đơn giản này:

ls -a | sort

2
Xuất sắc! Bất kỳ ý tưởng làm thế nào đường ống để sortlàm cho khối nhiều cột không được xoay vòng thành cột đơn?
msciwoj

@msciwoj chỉ cần lấy bất kỳ chuỗi nào được phân tách bằng khoảng trắng và in chúng được sắp xếp cách nhau bởi các dòng cuối
Ben

HOÀN HẢO! Tại sao câu hỏi này không được đánh dấu là câu trả lời thực sự!?
夏 期 劇場

3
Nó hoạt động ở đây vì hoàn nguyên lsvề ls -1(đầu ra một cột) khi đầu ra của nó không đi đến một thiết bị đầu cuối (và vô hiệu hóa trích dẫn / thay thế ký tự không thể in được; @Kusalananda, lsnếu bạn vẫn không tuân thủ POSIX). lsđầu ra đã được sắp xếp. Vì vậy, đường ống sortsẽ không làm gì cả, và tệ hơn là đầu ra (nếu tên tệp chứa ký tự dòng mới) hoặc không thành công cho tên tệp không phải là văn bản. ls -a | catsẽ tốt hơn. Hoặc thậm chí tốt hơn ls -A1như đã đề cập (và vì bạn thường muốn thay thế / trích dẫn khi được hiển thị trên thiết bị đầu cuối)
Stéphane Chazelas 23/03/18

1
@ StéphaneChazelas Lưu ý. lshành xử khác nhau khi đầu ra không phải là một thiết bị đầu cuối.
Kusalananda

3

Bạn không thể phân tích đầu ra của ls, hãy để một mình ls -lbởi vì dòng mới, giống như không gian là một ký tự hợp lệ như bất kỳ trong một tên tệp. Ngoài ra, bạn sẽ cần xem xét các liên kết tượng trưng có đầu ra như thế nào ... foo -> bar.

Tại sao bạn -lvẫn sử dụng nếu bạn chỉ muốn tên tệp?

Cứ làm đi:

for file in *; do
  ...
done

Nếu bạn muốn bao gồm các tệp chấm (ngoại trừ ...), tùy thuộc vào trình bao:

zsh:

for file in *(ND); do
  ...
done

bash:

shopt -s nullglob dotglob
for file in *; do
  ...
done

ksh93:

FIGNORE='@(.|..)'
for file in ~(N)*; do
  ...
done

POSIXly:

for file in .[!.]* ..?* *; do
  [ -e "$file" ] || [ -L "$file" ] || continue
  ...
done


1
ls -Al | tr -s ' ' | cut -f9- -d' '

nén nhiều khoảng trắng thành các khoảng trắng đơn lẻ với tr sau đó bạn có thể sử dụng cắt để phân chia trên các trường


1

Hãy thử ( bash, zsh, ksh93cú pháp):

find . -type f -print0 | while IFS= read -r -d '' filename; do
  ...
done

Điều này đi theo đệ quy và chỉ liệt kê trên các tệp thông thường (tức là không có thư mục hoặc liên kết tượng trưng / fifos / thiết bị ...).

Xem thêm:



-1
ls --file *|grep ^ 

Nó hiển thị những tập tin trong thư mục nào.


Tôi không nghĩ rằng điều này giải quyết câu hỏi.
Jeff Schaller
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.