Tập lệnh Shell của Linux cho mỗi tệp trong thư mục Lấy tên tệp và thực thi một chương trình


84

Tình huống:

Một thư mục trong hệ thống Linux. Tôi muốn lặp lại mọi tệp .xls trong một thư mục.

Thư mục này thường bao gồm nhiều thư mục khác nhau, nhiều kiểu tệp khác nhau (.sh, .pl, .csv, ...).

Tất cả những gì tôi muốn làm là lặp lại tất cả các tệp trong thư mục gốc và chỉ thực thi một chương trình trên các tệp .xls.

Biên tập :

Vấn đề là chương trình tôi phải thực hiện là 'xls2csv' để chuyển đổi từ định dạng .xls sang .csv. Vì vậy, đối với mỗi tệp .xls, tôi phải lấy tên tệp và nối nó vào .csv.

Ví dụ: tôi có tệp test.xls và các đối số của xls2csv là: xls2csv test.xls test.csv

Tôi có hiểu không?

Câu trả lời:


199

bash:

for f in *.xls ; do xls2csv "$f" "${f%.xls}.csv" ; done

Chỉ đơn giản là tuyệt vời! Hoạt động hoàn hảo! Cảm ơn bạn rất nhiều!
ThinkCode

6
Đây chính xác là những gì tôi đang tìm kiếm vì một lý do hoàn toàn khác. Chỉnh sửa một chút, và nó hoàn hảo cho nhu cầu cụ thể của tôi. Cảm ơn = D Và đối với bất kỳ ai không rõ điều này làm gì: $ {f% .ext} thay thế tên tệp mà không có phần mở rộng, vì vậy trong ví dụ này, nó sẽ hiển thị thành "filename.csv" thay vì "tên tệp. xls.csv ".
Frungi

Heh tôi đã lên Google "tệp foreach txt linux" và tìm thấy cái này. Đây chính là điều mà tôi cần, tôi đã thực sự cố gắng để sử dụng xls2csv nhưng figured tôi sẽ không tìm thấy bất kỳ kết quả tìm kiếm :) rằng
akiller

1
$ f sẽ có giá trị là * .xls nếu * .xls không khớp với bất kỳ tệp nào. Kiểm tra câu trả lời của tôi nếu đó là một vấn đề.
AndrewBourgeois

Hoặc bạn có thể chỉ cần thiết lập nullglobđể bỏ qua vòng lặp.
Ignacio Vazquez-Abrams

15
for i in *.xls ; do 
  [[ -f "$i" ]] || continue
  xls2csv "$i" "${i%.xls}.csv"
done

Dòng đầu tiên trong dokiểm tra nếu "phù hợp với" tập tin thực sự tồn tại, bởi vì trong trường hợp trận đấu không có gì trong bạn for, sự dosẽ được thực hiện với "* .xls" như $i. Điều này có thể là kinh khủng cho của bạn xls2csv.


13

Nhìn vào lệnh tìm .

Những gì bạn đang tìm kiếm là một cái gì đó giống như

find . -name "*.xls" -type f -exec program 

Đã đăng nó

find . -name "*.xls" -type f -exec xls2csv '{}' '{}'.csv;

sẽ thực hiện xls2csv file.xls file.xls.csv

Gần hơn với những gì bạn muốn.


find -maxdepth 1để loại trừ các thư mục con. Điều này cũng chuyển đổi test.xlsthành test.xls.csvthay vì test.csv. Vì vậy, không hoàn toàn những gì OP yêu cầu, nhưng khá gần.
ephemient

Việc sử dụng {}như một chuỗi con của một đối số thay vì toàn bộ một đối số là một phần mở rộng GNU, không được đảm bảo bởi đặc tả POSIX cho find. Do đó, câu trả lời này không nhất thiết phải di động đến các nền tảng không phải GNU.
Charles Duffy

4
find . -type f -name "*.xls" -printf "xls2csv %p %p.csv\n" | bash

bash 4 (đệ quy)

shopt -s globstar
for xls in /path/**/*.xls
do
  xls2csv "$xls" "${xls%.xls}.csv"
done

Giải pháp tuyệt vời. Tôi đã sử dụng điều này để cho phép tôi viết haml / scss và xây dựng thành html / css tại thời điểm thiết kế cho một dự án node.js.
Chris Kemp

1
Điều này hoàn toàn nguy hiểm nếu bạn không tin rằng tên tệp của mình không chứa những thứ như $(rm -rf /)... hoặc chỉ khoảng trắng.
Charles Duffy
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.