Использование результата команды в качестве аргумента в bash?
-
09-06-2019 - |
Вопрос
Чтобы создать список воспроизведения для всей музыки в папке, я использую следующую команду в bash:
ls > list.txt
Я хотел бы использовать результат страдающий (распечатать рабочий каталог) для имени списка воспроизведения.
Что-то вроде:
ls > ${pwd}.txt
Однако это не работает - может ли кто-нибудь сказать мне, какой синтаксис мне нужно использовать, чтобы сделать что-то подобное?
Редактировать: Как упоминалось в комментариях, pwd в конечном итоге предоставит абсолютный путь, поэтому мой список воспроизведения в каком-то каталоге будет называться .txt — ох!Так что мне придется подрезать путь.Спасибо, что заметили это — я бы, наверное, целую вечность задавался вопросом, куда делись мои файлы!
Решение
Лучший способ сделать это с помощью "$(command substitution)"
(Спасибо, Приземляться):
ls > "$(pwd).txt"
Иногда вы также увидите, что люди используют старую нотацию обратной кавычки, но это несколько недостатков с точки зрения вложения и побега:
ls > "`pwd`.txt"
Обратите внимание, что необработанная замена pwd
является абсолютным путем, поэтому приведенная выше команда создает файл с тем же именем в том же каталоге, что и рабочий каталог, но с .txt
расширение.Томас Каммейер отметил, что basename
Команда удаляет начальный каталог, поэтому в текущем каталоге будет создан текстовый файл с именем этого каталога:
ls > "$(basename "$(pwd)").txt"
Также спасибо erichui за то, что поднял проблему пробелов на пути.
Другие советы
Это эквивалентно решению с обратным кавычком:
ls > $(pwd).txt
Чтобы сделать буквально то, что вы сказали, вы можете попробовать:
ls > `pwd`.txt
который будет использовать полный путь, и это должно быть нормально.Обратите внимание, что если вы сделаете это в своем домашнем каталоге, который может быть в /home /hoboben, вы будете попробовать Create /home/hoboben.txt, текстовый файл в каталоге выше.
Это то, чего ты хотел?
Если бы вы хотели, чтобы каталог содержал файл, названный в честь него, вы получите базовое имя текущего каталога и добавили его с .txt к PWD.
Теперь вместо использования команды pwd...почему бы не использовать переменную среды PWD?
Например:
ls > $PWD.txt
или
ls > ${PWD}.txt
вероятно, это то, что вы пытались запомнить своим вторым примером.
Если вы находитесь в /home/hoboben и хотите создать /home/hoboben/hoboben.txt, попробуйте:
ls > ${PWD}/${PWD##*/}.txt
Если вы сделаете это, файл будет содержать собственное имя, поэтому чаще всего вы можете исправить это одним из нескольких способов.Вы можете перенаправить куда-нибудь еще и переместить файл или назвать файл, начинающийся с точки, чтобы скрыть его от команды ls, если вы не используете флаг -a (а затем, при необходимости, переименовать полученный файл).
Я пишу свои собственные сценарии для управления иерархией каталогов музыкальных файлов и использую подкаталоги с именем «.info», например, для хранения данных треков в некоторых запасных файлах (по сути, таким образом я «скрываю» метаданные).Все работает нормально, потому что мои потребности просты, а коллекция небольшая.
Я подозреваю, что проблема может заключаться в том, что в одном из имен каталогов есть пробелы.Например, если ваш рабочий каталог — «/home/user/music/artist name».Баш будет сбит с толку, думая, что вы пытаетесь перенаправить на /home/user/music/artist и name.txt.Вы можете исправить это с помощью двойных кавычек
ls > "$(pwd).txt"
Кроме того, вы можете не захотеть перенаправляться на $(pwd).txt.В приведенном выше примере вы должны перенаправить вывод в файл «/home/user/music/artist name.txt».
Синтаксис:
ls > `pwd`.txt
Это символ «`» под «~», а не обычная одинарная кавычка.
Использование описанного выше метода создаст файлы на один уровень выше вашего текущего каталога.Если вы хотите, чтобы все списки воспроизведения находились в одном каталоге, вам нужно сделать что-то вроде:
#!/bin/sh
MYVAR=`pwd | sed "s|/|_|g"`
ls > /playlistdir/$MYVAR-list.txt
удалить все, кроме имени каталога
ls >/playlistdir/${PWD##/*}.txt
вероятно, это не то, что вам нужно, потому что тогда вы не будете знать, где находятся файлы (если вы не измените команду ls)
заменить "/" на "_"
ls >/playlistdir/${PWD//\//_}.txt
но тогда плейлист будет выглядеть некрасиво и возможно даже не поместится в окно выбора
Таким образом, это даст вам как короткое читаемое имя, так и полезные пути внутри файла.
ext=.mp3 #leave blank for all files
for FILE in "$PWD/*$ext"; do echo "$FILE";done >/playlistdir/${PWD##/*}.txt