Посмотрите на этот пример:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope,$http) {
var getJoke = function(){
return $http.get('http://api.icndb.com/jokes/random').then(function(res){
return res.data.value;
});
}
getJoke().then(function(res) {
console.log(res.joke);
});
});
Как вы можете видеть, getJoke
возвращает разрешенное обещание (оно разрешено при возврате res.data.value
). Таким образом, вы ждете, пока запрос $ http.get не будет завершен, а затем выполнится console.log (res.joke) (как обычный асинхронный поток).
Это plnkr:
find . -name \*.mp3 | (
while read file; do
echo $file
done
)
Есть много способов обмануть этого кота. Я бы использовал вызов команды find:
for file in $(find . -name '*.mp3') do
echo $file
TITLE=$(id3info "$file" | grep '^=== TIT2' | sed -e 's/.*: //g')
ARTIST=$(id3info "$file" | grep '^=== TPE1' | sed -e 's/.*: //g')
echo "$ARTIST - $TITLE"
done
Если у вас есть пробелы в именах файлов, лучше использовать параметр -print0
для поиска; один из возможных способов заключается в следующем:
find . -name '*.mp3' -print0 | while read -d $'\0' file
do
echo $file
TITLE=$(id3info "$file" | grep '^=== TIT2' | sed -e 's/.*: //g')
ARTIST=$(id3info "$file" | grep '^=== TPE1' | sed -e 's/.*: //g')
echo "$ARTIST - $TITLE"
done
в качестве альтернативы вы можете сохранить и восстановить IFS
. Благодаря комментариям Дэвида В. и, в частности, указывая на то, что версия цикла while
также имеет то преимущество, что она будет обрабатывать очень большое количество файлов правильно, тогда как первая версия, которая расширяет $(find)
до for-loop не сможет работать в какой-то момент, поскольку расширение оболочки имеет ограничения.
Слишком многие из этих ответов используют расширение оболочки для хранения результатов поиска. Это не то, что вам нужно сделать легко.
Предположим, у меня 30 000 песен, а названия этих песен в среднем составляют около 30 символов. Допустим, мы даже не столкнемся с проблемой white space .
Моя находка вернет более 1 000 000 символов, и очень вероятно, что мой буфер командной строки не такой большой. Если бы я сделал что-то вроде этого:
for file in $(find -name "*.mp3")
do
echo "some sort of processing"
done
Проблема (помимо пробела в именах файлов) заключается в том, что ваш буфер командной строки просто отключит переполнение из find
. Это может даже сильно потерпеть неудачу.
Вот почему была создана команда xargs
. Он гарантирует, что буфер командной строки никогда не переполняется. Он будет выполнять команду, следующую за xargs
столько раз, сколько необходимо для защиты буфера командной строки:
$ find . -name "*.mp3" | xargs ...
Конечно, используя xargs
, этот способ все равно будет задыхаться на белом фоне, но современный реализации xargs
и find
имеют способ решить эту проблему:
$ find . -name "*.mp3 -print0 | xargs --null ...
Если вы можете гарантировать, что имена файлов не будут иметь вкладок или \n
(или двойных пробелов) в них , лучше всего найти поиск в цикле while:
find . -name "*.mp3" | while read file
do
Конвейер отправит файлы в while read
до заполнения буфера командной строки. Более того, read file
читается по всей строке и помещает все элементы, найденные в этой строке, в $file
. Это не идеально, потому что read
все еще ломается на пробел, поэтому имена файлов, такие как:
I will be in \n your heart in two lines.mp3
I love song names with multiple spaces.mp3
I \t have \t a \t thing \t for \t tabs.mp3.
По-прежнему будут работать. Переменная $file
увидит их как:
I will be in
your heart in two lines.mp3
I love song names with multiple spaces.mp3
I have a thing for tabs.mp3.
Чтобы обойти эту проблему , вы должны использовать find ... -print0
для использования нулей в качестве входных разделителей. Затем либо измените IFS
на использование нулей, либо используйте параметр -d\0
в инструкции while при чтении в оболочке BASH.
Это работает с большинством имен файлов (включая пробелы), но не с новыми символами, вкладками или двойными пробелами.
find . -type f -name '*.mp3' | while read i; do
echo "$i"
done
Это работает со всеми именами файлов.
find . -type f -name '*.mp3' -print0 | while IFS= read -r -d '' i; do
echo "$i"
done
Но если вы только хотите запустить одну команду, вы можете использовать пример xargs
:
find . -type f -name '*.mp3' -print0 | xargs -0 -l echo
Похоже, вы ищете команду find. Я не тестировал это, но что-то вроде этого:
files=(`find . -name *.mp3`)
for file in "${files[@]}"; do
echo $file TITLE="id3info "$file" | grep '^=== TIT2' | sed -e 's/.*: //g'" ARTIST="id3info "$file" | grep '^=== TPE1' | sed -e 's/.*: //g'"
done
EDIT: использование массива делает команду безопасной для файлов с пробелами в их именах.