2011-05-02 32 views
5

Tôi đang cố gắng để có được kịch bản của tôi để ls tất cả các file dưới dạng "$ biến". *

tham số luôn luôn là một tập tin với phần mở rộng 0,001 Tôi muốn tìm tất cả các file có cùng tên nhưng phần mở rộng khác nhau, ví dụ: $ file.002, file.003, vv Eg .:

first="$1" 
others=${first%.001} 
ls $others"*" 

vấn đề của tôi là file được đặt tên file[success].mpg.001 và những gì được làm thức ăn cho ls là file[success].mpg* cung cấp cho tôi ls: cannot access file[success].mpg*: No such file or directoryls nhu cầu để xem:

file\[success\].mpg* 

Tôi đã cố gắng tất cả mọi thứ, là điều tôi đã thông báo là ls ăn tham số $ 1 hoạt động, nhưng không phải nếu ăn $ file sau khi tôi đã thực hiện file = $ 1. Vì vậy, tôi đoán làm thế nào để thay đổi biến thành một tham số?

Trả lời

6

Bạn có thể sử dụng bash 's printf lệnh để định dạng chuỗi. Bên cạnh đó bạn không cần phải trích dẫn *:

#!/bin/bash 
first="$1" 
others=$(printf %q "${first%.001}") 
ls $others* 

printf %q định dạng lại chuỗi trong một định dạng mà có thể được sử dụng như đầu vào vỏ (liên quan đến người đàn ông trang bash 's).

chỉnh sửa liên quan đến nhận xét:
Giải pháp trên không hoạt động với khoảng trắng trong tên tệp. Đối với những trường hợp (như một số câu trả lời khác đã đề cập) nó tốt hơn không sử dụng printf nhưng trích dẫn đúng tất cả các biến:

#!/bin/bash 
first="$1" 
others="${first%.001}" 
ls -- "$others"* 
+0

thankyou rất nhiều! – geekmagii

+0

Tôi rất vui vì tôi có thể giúp bạn. – bmk

+1

Điều này làm việc cho các tệp có dấu ngoặc trong tên nhưng không hoạt động cho các ký tự lẻ khác như dấu cách. Ví dụ, tôi đã thử './findfiles1 'test [success] .mpg.001" ', và nó phân tích cú pháp đó là hai tên tập tin và không tìm thấy:' ls: \ [success \]. Mpg *: Không có tập tin như vậy hoặc thư mục' 'ls: test \: Không có tệp hoặc thư mục nào'. –

1

Sử dụng tìm thay vì ls:

$ ls weg.* 
ls: weg.*: No such file or directory 
$ find . -name weg.\* 
$ 
+1

[Vì lý do nhiều hơn một] (http: // mywiki.wooledge.org/ParsingLs) – l0b0

+0

tìm. -tên tệp [success] .mpg * không tìm thấy gì cả. – geekmagii

+1

từ câu trả lời của l0b0 tôi đoán tôi chỉ nên sử dụng một cách khác hơn ls – geekmagii

2

Bạn không phải là quá xa. Sửa chữa đầu tiên của tôi đang thay đổi dòng 3 thành những điều sau đây:

ls -- "${others}".* 

Điều này sẽ mở rộng $others và cho phép sự phát triển xảy ra. Đó là trách nhiệm của vỏ để mở rộng * vào danh sách tất cả tên tệp phù hợp. Danh sách tên tập tin sau đó được gửi đến ls. Có vẻ như trong hầu hết các trường hợp ls sẽ thấy một cái gì đó như thế này:

file1.001 file1.002 file1.003 ... 

Tuy nhiên, khi không có file có mặt, vỏ vượt qua glob để ls và nó sẽ thấy dấu hoa thị:

file1.* 

Do đó, dòng của bạn, ls $others"*" gắn thêm dấu hoa thị mà ls sẽ thấy.

Trừ khi bạn có tên tệp file1.* (có dấu hoa thị), ls sẽ không thành công.

Một lựa chọn khác là sử dụng basename:

first="$1" 
others=`basename -- "$first" .001` 
ls -- "${others}".* 

Sử dụng basename mang đến cho bạn những lợi thế mà nó có thể loại bỏ thư mục, vv

Tuy nhiên, như những người khác đã chỉ ra, tùy thuộc vào những gì bạn đang làm với danh sách tệp, find có thể tốt hơn.

CHỈNH SỬA: Dấu gạch nối kép không hoạt động trên tất cả các biến thể * nix nhưng nói với các lệnh lsbasename mà không có đối số nào khác theo sau. Trích dẫn các biến của bạn có thể là một phương pháp hay nhất nhưng tôi thích sự đơn giản của việc loại bỏ chúng trừ khi dữ liệu không được tin cậy. Biết dữ liệu và báo giá của bạn một cách thích hợp.

+0

Các biến của bạn không được trích dẫn đúng cách, điều này gây ra vấn đề nếu tên tệp chứa dấu cách hoặc các ký tự "đặc biệt" khác. Sử dụng 'ls -" $ else "*' và 'tên cơ sở -" $ đầu tiên "' thay thế. – Philipp

+0

@Philipp - Đủ công bằng, được chỉnh sửa. –

5

Bạn nên trích dẫn biến, không phải là ký tự đại diện:

ls -- "$others"* 

Các dấu gạch ngang đôi dừng tìm kiếm cho các tùy chọn để mã này nên làm việc ngay cả khi others bắt đầu với một dấu gạch ngang.

Lưu ý rằng ls thường không phải là giải pháp sai trong tập lệnh. Chỉ sử dụng nó nếu bạn thực sự muốn in danh sách, ví dụ: ở định dạng dài:

ls -l -- "$others"* 

Nếu bạn muốn in chỉ có tên, bạn không cần phải ls tại tất cả:

echo "$others"* 

Đáng tiếc là bạn không thể sử dụng -- với echo. Tuy nhiên, nếu bạn muốn có một mảng của tên tập tin, sử dụng

filenames=("$others"*) 

Và bạn nên muốn để lặp qua chúng, sử dụng

for filename in "$others"* 
Các vấn đề liên quan