74

To create a playlist for all of the music in a folder, I am using the following command in bash:

ls > list.txt

I would like to use the result of the pwd command for the name of the playlist.

Something like:

ls > ${pwd}.txt

That doesn't work though - can anyone tell me what syntax I need to use to do something like this?

Edit: As mentioned in the comments pwd will end up giving an absolute path, so my playlist will end up being named .txt in some directory - d'oh! So I'll have to trim the path. Thanks for spotting that - I would probably have spent ages wondering where my files went!

Enlico
  • 23,259
  • 6
  • 48
  • 102
HoboBen
  • 3,421
  • 2
  • 26
  • 22

7 Answers7

91

The best way to do this is with "$(command substitution)" (thanks, Landon):

ls > "$(pwd).txt"

You will sometimes also see people use the older backtick notation, but this has several drawbacks in terms of nesting and escaping:

ls > "`pwd`.txt"

Note that the unprocessed substitution of pwd is an absolute path, so the above command creates a file with the same name in the same directory as the working directory, but with a .txt extension. Thomas Kammeyer pointed out that the basename command strips the leading directory, so this would create a text file in the current directory with the name of that directory:

ls > "$(basename "$(pwd)").txt"

Also thanks to erichui for bringing up the problem of spaces in the path.

that other guy
  • 116,971
  • 11
  • 170
  • 194
John Calsbeek
  • 35,947
  • 7
  • 94
  • 101
  • But note that using backticks or $( ) will still fork another shell... using the environment variable is the least-cost method. – Thomas Kammeyer Sep 12 '08 at 03:02
  • True, but the question title and tags are generalized, so the answer might as well be generalized too. An environment variable is the "better" option in this case, but it isn't a general answer to the question. – John Calsbeek Sep 12 '08 at 03:06
7

This is equivalent to the backtick solution:

ls > $(pwd).txt
Landon
  • 15,166
  • 12
  • 37
  • 30
6

To do literally what you said, you could try:

ls > `pwd`.txt

which will use the full pathname, which should be fine. Note that if you do this in your home directory, which might be in /home/hoboben, you will be trying the create /home/hoboben.txt, a text file in the directory above.

Is this what you wanted?

If you wanted the directory to contain a file named after it, you would get the basename of the current directory and append that with .txt to the pwd.

Now, rather than use the pwd command... why not use the PWD environment variable?

For example:

ls > $PWD.txt

or

ls > ${PWD}.txt

is probably what you were trying to remember with your second example.

If you're in /home/hoboben and you want to create /home/hoboben/hoboben.txt, try:

ls > ${PWD}/${PWD##*/}.txt

If you do this, the file will contain its own name, so most often, you would remedy this in one of a few ways. You could redirect to somewhere else and move the file or name the file beginning with a dot to hide it from the ls command as long as you don't use the -a flag (and then optionally rename the resulting file).

I write my own scripts to manage a directory hierarchy of music files and I use subdirectories named ".info", for example, to contain track data in some spare files (basically, I "hide" metadata this way). It works out okay because my needs are simple and my collection small.

Thomas Kammeyer
  • 4,457
  • 21
  • 30
5

I suspect the problem may be that there are spaces in one of the directory names. For example, if your working directory is "/home/user/music/artist name". Bash will be confused thinking that you are trying to redirect to /home/user/music/artist and name.txt. You can fix this with double quotes

ls > "$(pwd).txt"

Also, you may not want to redirect to $(pwd).txt. In the example above, you would be redirecting the output to the file "/home/user/music/artist name.txt"

erichui
  • 2,761
  • 2
  • 20
  • 20
4

The syntax is:

ls > `pwd`.txt

That is the '`' character up underneath the '~', not the regular single quote.

John Meagher
  • 22,808
  • 14
  • 54
  • 57
2

Using the above method will create the files one level above your current directory. If you want the play lists to all go to one directory you'd need to do something like:

#!/bin/sh

MYVAR=`pwd | sed "s|/|_|g"`
ls > /playlistdir/$MYVAR-list.txt
Mark Nold
  • 5,638
  • 7
  • 31
  • 33
0

to strip all but the directory name

ls >/playlistdir/${PWD##/*}.txt

this is probably not what you want because then you don't know where the files are (unless you change the ls command)

to replace "/" with "_"

ls >/playlistdir/${PWD//\//_}.txt

but then the playlist would look ugly and maybe not even fit in the selection window

So this will give you both a short readable name and usable paths inside the file

ext=.mp3 #leave blank for all files
for FILE in "$PWD/*$ext"; do echo "$FILE";done >/playlistdir/${PWD##/*}.txt
technosaurus
  • 7,676
  • 1
  • 30
  • 52