Usare il risultato di un comando come argomento in bash?
-
09-06-2019 - |
Domanda
Per creare una playlist per tutta la musica in una cartella, sto usando il seguente comando in bash:
ls > list.txt
Vorrei utilizzare il risultato di pwd (directory di lavoro di stampa) comando per il nome della playlist.
Qualcosa di simile a:
ls > ${pwd}.txt
Tuttavia non funziona: qualcuno può dirmi quale sintassi devo usare per fare qualcosa del genere?
Modificare: Come accennato nei commenti, pwd finirà per fornire un percorso assoluto, quindi la mia playlist finirà per essere denominata .txt in qualche directory - d'oh!Quindi dovrò tagliare il percorso.Grazie per averlo notato: probabilmente avrei passato molto tempo a chiedermi dove fossero finiti i miei file!
Soluzione
Il modo migliore per farlo è con "$(command substitution)"
(Grazie, Atterrare su):
ls > "$(pwd).txt"
A volte vedrai anche persone usare la vecchia notazione backtick, ma così è stato diversi inconvenienti in termini di nidificazione e fuga:
ls > "`pwd`.txt"
Si noti che la sostituzione non elaborata di pwd
è un percorso assoluto, quindi il comando precedente crea un file con lo stesso nome nella stessa directory della directory di lavoro, ma con un .txt
estensione.Thomas Kammeyer ha sottolineato che il basename
Il comando rimuove la directory principale, quindi creerebbe un file di testo nella directory corrente con il nome di quella directory:
ls > "$(basename "$(pwd)").txt"
Grazie anche a erichui per aver sollevato il problema degli spazi nel percorso.
Altri suggerimenti
Ciò è equivalente alla soluzione del backtick:
ls > $(pwd).txt
Per fare letteralmente quello che hai detto, potresti provare:
ls > `pwd`.txt
che utilizzerà il nome del percorso completo, il che dovrebbe andare bene.Tieni presente che se lo fai nella tua home directory, che potrebbe essere in /home /hoboben, proverai Create /home/hoboben.txt, un file di testo nella directory sopra.
Questo è quello che volevi?
Se volevi che la directory contenga un file che prese il nome da questo, otterrai il basename della directory corrente e lo aggiungi con .txt al PWD.
Ora, invece di usare il comando pwd...perché non utilizzare la variabile d'ambiente PWD?
Per esempio:
ls > $PWD.txt
O
ls > ${PWD}.txt
è probabilmente quello che stavi cercando di ricordare con il tuo secondo esempio.
Se ti trovi in /home/hoboben e vuoi creare /home/hoboben/hoboben.txt, prova:
ls > ${PWD}/${PWD##*/}.txt
Se lo fai, il file conterrà il proprio nome, quindi molto spesso potresti rimediare a questo in uno dei pochi modi.Potresti reindirizzare da qualche altra parte e spostare il file o nominare il file che inizia con un punto per nasconderlo dal comando ls purché non utilizzi il flag -a (e quindi facoltativamente rinominare il file risultante).
Scrivo i miei script per gestire una gerarchia di directory di file musicali e utilizzo sottodirectory denominate ".info", ad esempio, per contenere i dati delle tracce in alcuni file di riserva (sostanzialmente, "nascondo" i metadati in questo modo).Funziona bene perché le mie esigenze sono semplici e la mia collezione è piccola.
Sospetto che il problema potrebbe essere che ci siano spazi in uno dei nomi di directory.Ad esempio, se la tua directory di lavoro è "/home/utente/musica/nome artista".Bash sarà confuso pensando che stai tentando di reindirizzare a /home/utente/musica/artista e nome.txt.Puoi risolvere questo problema con le virgolette doppie
ls > "$(pwd).txt"
Inoltre, potresti non voler reindirizzare a $(pwd).txt.Nell'esempio sopra, reindirizzeresti l'output al file "/home/user/music/artist name.txt"
La sintassi è:
ls > `pwd`.txt
Questo è il carattere "" sotto "~", non la normale virgoletta singola.
L'utilizzo del metodo sopra creerà i file un livello sopra la directory corrente.Se vuoi che le playlist vadano tutte in una directory dovresti fare qualcosa del tipo:
#!/bin/sh
MYVAR=`pwd | sed "s|/|_|g"`
ls > /playlistdir/$MYVAR-list.txt
per rimuovere tutto tranne il nome della directory
ls >/playlistdir/${PWD##/*}.txt
questo probabilmente non è quello che vuoi perché in questo caso non sai dove sono i file (a meno che non cambi il comando ls)
per sostituire "/" con "_"
ls >/playlistdir/${PWD//\//_}.txt
ma poi la playlist sembrerebbe brutta e forse non entrerebbe nemmeno nella finestra di selezione
Quindi questo ti darà sia un nome breve leggibile che percorsi utilizzabili all'interno del file
ext=.mp3 #leave blank for all files
for FILE in "$PWD/*$ext"; do echo "$FILE";done >/playlistdir/${PWD##/*}.txt