Как вставить результаты нескольких команд в файл как часть моего потока sed? - PullRequest
0 голосов
/ 12 марта 2012

Я использую программное обеспечение DJing на Linux (xwax), которое использует скрипт сканирования ( видимый здесь ), который компилирует все музыкальные файлы, доступные для программного обеспечения, и выводит строку, содержащую путь к имени файла а затем название mp3. Например, если он сканирует path-to-mp3 / Artist - Test.mp3, он выдаст строку примерно так:

path-to-mp3/Artist - Test.mp3[tab]Artist - Test

Я пометил все мои mp3 с информацией BPM через инструмент id3v2 и у меня есть метод командной строки для извлечения этой информации следующим образом:

id3v2 -l name-of-mp3.mp3 | grep TBPM | cut -D: -f2

Это выплевывает просто числовой BPM для меня. То, что я хотел бы сделать, это добавить число BPM из приведенной выше команды как часть сценария сканирования xwax, но я не уверен, как вставить эту команду в середине сценария . Я бы хотел, чтобы он генерировал:

path-to-mp3/Artist - Test.mp3[tab][bpm]Artist - Test

Есть идеи?

1 Ответ

1 голос
/ 12 марта 2012

Мне не понятно , где в этом скрипте вы хотите вставить номер BPM, но идея такова:

  • Чтобы вставить вывод одногоКоманда в аргументах другого, вы можете использовать обозначение «подстановка команд» `...` или $(...).Например, это:

    rm $(echo abcd)
    

    запускает команду echo abcd и подставляет ее вывод (abcd) в общую команду;так что это эквивалентно просто rm abcd.Он удалит файл с именем abcd.

  • Выше не работает внутри одинарных кавычек.Если вы хотите, вы можете просто поставить его вне кавычек, как я делал в приведенном выше примере;но обычно безопаснее помещать его в двойные кавычки (чтобы предотвратить нежелательную постобработку).Любой из них:

    rm "$(echo abcd)"
    rm "a$(echo bc)d"
    

    удалит файл с именем abcd.

  • В вашем случае вам нужно встроить подстановку команд в серединуаргумент, который в основном однократный.Вы можете сделать это, просто поместив строки в одинарных кавычках и строки в двойных кавычках рядом друг с другом без пробела, так что Bash объединит их в один аргумент.(Это также работает со строками без кавычек.) Например, любой из этих:

    rm a"$(echo bc)"d
    rm 'a'"$(echo bc)"'d'
    

    удалит файл с именем abcd.


Отредактировано, чтобы добавить: ОК, я думаю, я понимаю, что вы пытаетесь сделать.У вас есть команда, которая (1) выводит все файлы в указанном каталоге (и любые подкаталоги и т. Д.), По одному на строку, или (2) выводит содержимое файла, где содержимое этого файла являетсясписок файлов, по одному в строке.Таким образом, в любом случае выводится список файлов, по одному на строку.И вы добавляете этот список в команду:

sed -n '
{
# /[<num>[.]] <artist> - <title>.ext
s:/\([0-9]\+.\? \+\)\?\([^/]*\) \+- \+\([^/]*\)\.[A-Z0-9]*$:\0\t\2\t\3:pi
t

# /<artist> - <album>[/(Disc|Side) <name>]/[<ABnum>[.]] <title>.ext
s:/\([^/]*\) \+- \+\([^/]*\)\(/\(disc\|side\) [0-9A-Z][^/]*\)\?/\([A-H]\?[A0-9]\?[0-9].\? \+\)\?\([^/]*\)\.[A-Z0-9]*$:\0\t\1\t\6:pi
t

# /[<ABnum>[.]] <name>.ext
s:/\([A-H]\?[A0-9]\?[0-9].\? \+\)\?\([^/]*\)\.[A-Z0-9]*$:\0\t\t\2:pi
}
'

, которая запускает сценарий sed над этим списком.Вам нужно, чтобы все строки замены изменились с \0\t... на \0\tBPM\t..., где BPM - это число ударов в минуту, вычисленное по вашей команде.Правильно?И вам нужно вычислить это число BPM отдельно для каждого файла, поэтому вместо того, чтобы полагаться на неявное построчное зацикливание sed, вам нужно обрабатывать циклы самостоятельно и обрабатывать по одной строке за раз.Правильно?

Итак, вы должны изменить приведенную выше команду на эту:

while read -r LINE ; do # loop over the lines, saving each one as "$LINE"
    BPM=$(id3v2 -l "$LINE" | grep TBPM | cut -D: -f2) # save BPM as "$BPM"
    sed -n '
    {
    # /[<num>[.]] <artist> - <title>.ext
    s:/\([0-9]\+.\? \+\)\?\([^/]*\) \+- \+\([^/]*\)\.[A-Z0-9]*$:\0\t'"$BPM"'\t\2\t\3:pi
    t

    # /<artist> - <album>[/(Disc|Side) <name>]/[<ABnum>[.]] <title>.ext
    s:/\([^/]*\) \+- \+\([^/]*\)\(/\(disc\|side\) [0-9A-Z][^/]*\)\?/\([A-H]\?[A0-9]\?[0-9].\? \+\)\?\([^/]*\)\.[A-Z0-9]*$:\0\t'"$BPM"'\t\1\t\6:pi
    t

    # /[<ABnum>[.]] <name>.ext
    s:/\([A-H]\?[A0-9]\?[0-9].\? \+\)\?\([^/]*\)\.[A-Z0-9]*$:\0\t'"$BPM"'\t\t\2:pi
    }
    ' <<<"$LINE" # take $LINE as input, rather than reading more lines
done

(где единственное изменение в самом скрипте sed заключалось в вставке '"$BPM"'\t в нескольких местахчтобы перейти от одиночных кавычек к двойным кавычкам, затем вставьте BPM, затем вернитесь к одиночным кавычкам и добавьте вкладку).

...