bash - перенаправить ls в пользовательский скрипт - PullRequest
0 голосов
/ 13 марта 2012

Для колледжа я пишу скрипт для чтения и отображения тегов id3 в mp3-файлах. Аргументами будут файлы, т. Е.

./id3.sh file1.mp3 file2.mp3 morefiles.mp3

Я могу прочитать аргументы, используя $0, $1 и т. Д., И получить число аргументов с помощью $#. как я могу получить его для чтения вывода команды ls?

ls *.mp3 | ./id3.sh

Ответы [ 6 ]

5 голосов
/ 13 марта 2012

Попробуйте это:

ls *.mp3 | xargs id3.sh
3 голосов
/ 13 марта 2012

Команда ls *.mp3 > ./id3.sh перезапишет ваш скрипт id3.sh списком mp3. Вы можете попробовать это:

./id3.sh `ls *.mp3`

РЕДАКТИРОВАТЬ: на самом деле, о чем я думал? Есть ли причина, по которой вы просто не можете этого сделать?

./id3.sh *.mp3
2 голосов
/ 13 марта 2012

Я бы предложил использовать pipe и xargs с аргументом -n , в приведенном ниже примере сценарий id3.sh будет вызываться с не более 10 файлы, перечисленные ls *.mp3. Это очень важно, особенно если в списке могут быть hounreds или тысячи файлов. Если вы пропустите -n 10, тогда ваш скрипт будет называться только один раз со всем списком. Если список слишком длинный, ваша система может отказать в запуске вашего скрипта. Вы можете поэкспериментировать, сколько файлов при каждом вызове вашего скрипта обрабатывать (например, что более эффективно в вашем случае).

ls *.mp3 | xargs -n 10 id3.sh

тогда вы можете прочитать файлы в вашем id3.sh сценарии, подобном этому

while [ "$1" != "" ]; do
    #next file available in ${1}
    shift
done
1 голос
/ 14 марта 2012

Любое решение, включающее расширение *.mp3, рискует потерпеть неудачу, если число файлов .mp3 настолько велико, что результирующее расширение *.mp3 превышает ограничение оболочки. Решения, прежде всего, имеют эту проблему:

ls *.mp3 | ...
for file in *.mp3; do ...

На самом деле, хотя ls *.mp3|xargs ... - хорошее начало, но у него та же проблема, потому что требуется, чтобы оболочка раскрыла список *.mp3 и использовала этот список в качестве аргументов командной строки для команды ls.

Один из способов правильно обработать произвольное количество файлов:

find . -maxdepth 1 -iname '*.mp3'|while read f; do
    do_something_one_file_at_a_time.sh "$f"
done

OR:

find . -maxdepth 1 -iname '*.mp3' -print0|xargs -0 do_something.sh

(Оба варианта имеют побочную выгоду от правильной обработки имен файлов с пробелами, например, «Капли дождя падают на мою голову.mp3».

Обратите внимание, что в do_something.sh вам нужно сделать for file in "$@"; do ..., а не просто for file in $*;do ... или for file in $@; do .... Также обратите внимание, что решение amit_g ломается, если есть имена файлов с пробелами.)

0 голосов
/ 13 марта 2012

Что не так с ./id3.sh *.mp3?Это безопаснее, чем любое решение с ls, и обеспечивает точно такие же функции глобализации.Здесь нет необходимости в xargs, если только вы не используете старое ядро ​​ и имеют огромное количество файлов .

0 голосов
/ 13 марта 2012
./id3.sh *.mp3 # if the number of files is not too many

или

ls *.mp3 | xargs -n 10 ./id3.sh # if the number of files could be too many

тогда в id3.sh

while [ "$1" != "" ]
do
    filename=$1

    #do whatever with $filename

    shift
done
...