Tại sao lệnh xargs này không hoạt động?


14

Tôi muốn xóa tất cả các phần mở rộng .sh vì vậy đã làm điều này:

ls *.sh | xargs -I {} mv {} `basename {} .sh`

Tuy nhiên, nó không hoạt động, nó hoạt động như basenametrả về tên tệp không thay đổi.

Tại sao nó lại hành xử theo cách đó?

Ví dụ, điều này hoạt động:

ls *.sh | xargs -I {} echo `basename {}.jpg .jpg`;

CHỈNH SỬA :

Giải pháp: trích dẫn đơn ngăn chặn `basename ...`đánh giá bằng shell trước khi lệnh được chạy.

ls *.sh | xargs -I {}  sh -c 'mv {} `basename {} .sh`'

Câu trả lời:


12

Bởi vì lệnh basename được chạy trước khi đường ống được chạy. Để thực hiện công việc này, bạn cần xargs để thực hiện tên cơ sở và bạn có thể làm điều đó với sh -c, ví dụ:

ls *.sh | xargs -L1 sh -c 'basename $1 .sh' dummy

Ghi chú:

  • Nếu bạn không cho biết xargsnơi chèn tên tệp, chúng sẽ được thêm vào cuối dòng lệnh.
  • Bạn nên sử dụng công -L1tắc hoặc tương đương của nó, vì vậy xargschỉ chuyển một đối số cho sh.
  • Sử dụng đầu ra của lscó thể có tác dụng không mong muốn .

Biên tập

Đã xóa các tùy chọn không dùng nữa, cảm ơn TechZilla


3
Điểm đầu tiên của bạn là không chính xác, trừ khi bạn có nghĩa là mặc định tương ứng với -itùy chọn, nhưng các tùy chọn 'cổ điển' đó đã không được chấp nhận. Ví dụ: chỉ sử dụng một tùy chọn / dòng, trang man POSIX mới khuyến nghị -L1. Để gọi hành vi cũ của -i, trang khuyến nghị -I'{}'tùy chọn.
JM Becker

Vì vậy, nó thực sự là về các biểu tượng '' thay vì "". Tôi đoán 'ngăn chặn đánh giá shell của ``. Xem các chỉnh sửa của tôi.
Majkinetor

@TechZilla: cảm ơn đã sửa chữa. @majkinetor: có và không, bạn cần trì hoãn việc đánh giá, nhưng tôi không nghĩ bạn có thể sử dụng backticks (`).
Thor

1
@majkinetor: ah, tôi hiểu ý của bạn lúc này. Để đổi tên các tập tin theo cách này, tôi muốn sử dụng rename, ví dụ : rename 's/\.sh//' *.sh. Hãy thử đầu tiên với Dry-run ( -n).
Thor

1
@majkinetor: renamehoạt động rất tốt và khá đơn giản, nhưng hãy nhớ rằng nó rất phân phối cụ thể. Các bản phân phối dựa trên RHEL và Debian cung cấp các renamelệnh khác nhau , vì vậy người ta phải ghi nhớ điều đó khi tạo các tập lệnh phân phối chéo.
JM Becker

4

Tôi không chắc về câu hỏi của bạn, bạn có thực sự hỏi tại sao dòng đầu tiên của bạn không hoạt động không? Hoặc bạn đang tìm kiếm một phương pháp thích hợp để đổi tên tất cả các tệp .sh?

Giả sử đó là phương pháp sạch nhất, tôi thích chuẩn bị các tùy chọn lệnh trước đó xargs. Để xóa phần mở rộng tệp .sh, tôi thường xem xét phương pháp này,

 find -maxdepth 1 -type f -iname '*.sh'  | sed 'p;s_.sh$__' | xargs -L2 mv
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.