Сценарий оболочки Linux для каждого файла в каталоге. Возьмите имя файла и выполните программу.


85

Сценарий:

Папка в системе Linux. Я хочу просмотреть каждый файл .xls в папке.

Эта папка обычно состоит из различных папок, файлов разных типов (.sh, .pl, .csv, ...).

Все, что я хочу сделать, это перебрать все файлы в корне и выполнить программу только для файлов .xls.

Редактировать :

Проблема в том, что программа, которую я должен выполнить, - это xls2csv для преобразования из формата .xls в .csv. Итак, для каждого файла .xls я должен взять имя файла и добавить его в .csv.

Например, у меня есть файл test.xls, и аргументы для xls2csv: xls2csv test.xls test.csv

Я имел смысл?

Ответы:


200

bash:

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

Просто потрясающе! Прекрасно работает! Спасибо огромное!
ThinkCode,

6
Это как раз то, что я искал по совершенно другой причине. Небольшое редактирование, и это идеально подходит для моей конкретной потребности. Спасибо = D И для всех, кто не понимает, что это делает: $ {f% .ext} заменяет имя файла без расширения, поэтому в этом примере он будет отображать в "filename.csv", а не в "filename. xls.csv ".
Frungi 02

Хех. Я погуглил "linux foreach txt file" и нашел это. Это было именно то, что мне было нужно, я на самом деле пытался использовать xls2csv, но решил, что не найду никаких результатов, ища это :)
akiller

1
$ f будет иметь значение * .xls, если * .xls не соответствует ни одному файлу. Проверьте мой ответ, если это проблема.
AndrewBourgeois

Или вы можете просто установить nullglob, чтобы пропустить цикл.
Игнасио Васкес-Абрамс

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

Первая строка в doпроверке проверяет, существует ли «соответствующий» файл на самом деле, потому что если в вашем файле ничего не найдено for, doон будет выполнен с «* .xls» как $i. Это может быть ужасно для вашего xls2csv.


13

Посмотрите на команду find .

Вы ищете что-то вроде

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

Опубликовать править

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

выполнит xls2csv file.xls file.xls.csv

Ближе к тому, что вы хотите.


find -maxdepth 1чтобы исключить подпапки. Это также преобразуется test.xlsв test.xls.csvвместо test.csv. Так что не совсем то, о чем просил OP, но довольно близко.
ephemient

Использование {}в качестве подстроки аргумента, а не всего аргумента, является расширением GNU, и не гарантируется спецификацией POSIX для find. Таким образом, этот ответ не обязательно переносится на платформы, отличные от GNU.
Чарльз Даффи

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

bash 4 (рекурсивный)

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

Отличное решение. Я использовал это, чтобы позволить мне писать haml / scss и встраивать в html / css во время разработки для проекта node.js.
Крис Кемп

1
Это совершенно опасно, если вы не уверены, что ваши имена файлов не содержат таких вещей, как $(rm -rf /)... или просто пробелы.
Чарльз Даффи
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.