获取目录列表作为嵌套for循环的变量以创建html

时间:2015-07-30 04:10:30

标签: bash

我有以下命令:

$ ls -alt|head -30

产生:

total 1891268

drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jul 24 03:03 Beenie Man - Blessed (1995) - [MP3-V0]
drwxrwxr-- 940 ikwyl6 http         69632 Jul 24 02:54 .
drwxr-xr-x   2 ikwyl6 http          4096 Jul 21 05:38 Ratatat - Magnifique (2015) [V0]
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jul 21 03:45 The Chemical Brothers - Born in the Echoes (2015) - CD V0
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jul 21 03:38 Wilco - Star Wars (2015) [V0]
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jul 19 01:45 The Jon Spencer Blues Explosion - Freedom Tower - No Wave Dance Party 2015 - 2015 (WEB - MP3 - V0)
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jun 21 17:17 Kendrick Lamar - To Pimp A Butterfly (2015) - WEB V0
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jun 21 17:15 Atmosphere - Sad Clown Bad Dub I (1999) [MP3-192]
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jun 21 17:15 Joel Plaskett- The Park Avenue Sobriety Test (2015) [V0]
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jun 21 17:11 Buena Vista Social Club - 2015 - Lost And Found [V0]
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jun 21 17:08 Florence + The Machine - How Big, How Blue, How Beautiful (Deluxe Edition) (2015) [V0]
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jun 21 17:08 The Prodigy - The Day Is My Enemy [2015](V0)
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jun 21 17:07 Death Cab For Cutie - Kintsugi (2015) - WEB V0
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jun 21 17:07 Sufjan Stevens - Carrie & Lowell (2015) [V0]
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jun 21 17:02 Aesop Rock-Cat Food -2014-V0
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jun 21 16:59 Hot Chip - Why Make Sense (2015) [v0]
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jun 21 16:59 Outkast- SouthernPlayalistiCadillacMuzik [V0]
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jun 21 16:53 Beirut - No No No (Single) (2015) - WEB V0
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jun 21 16:52 Jedi_Mind_Tricks-The_Thief_and_the_Fallen-2015-NOiR
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jun 21 16:46 Built To Spill - Untethered Moon (2015) [v0]
drwxr-xr-x   3 root     root          4096 Jun 12 22:18 ..
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Feb  3 03:23 Belle and Sebastian - Girls in Peacetime Want to Dance (2015) MP3 320
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Feb  3 03:19 Caribou - Our Love (2014) [v0]
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Feb  3 03:06 Bob Dylan - Shadows in the Night (2015) [V0]
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Jan  2  2015 The Smashing Pumpkins - Monuments to an Elegy - 2014 (WEB V0)
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Dec 26  2014 .sync-pi
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Dec  2  2014 AC-DC - Rock or Bust (2014) [V0]
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Dec  2  2014 The Decemberists_What a Terrible World, What a Beautiful World
drwxr-xr-x   2 ikwyl6 ikwyl6      4096 Nov 28  2014 Wu-Tang Clan - A Better Tomorrow (2014) - WEB V0

我希望能够遍历每个目录并使用添加的HTML列出其中的mp3。我知道如何在特定目录上执行此操作,但这样做:

for I in ls Wilco\ -\ Star\ Wars\ \(2015\)\ \[V0\]/*; do echo "<li><a href=\"#\" data-src=\"music/$I\">$I</a></li>"; done

给出了我想要的每个mp3行的最终结果(为简单起见只显示1行):

<li><a href="#" data-src="music/Wilco - Star Wars (2015) [V0]/01 - EKG.mp3">Wilco - Star Wars (2015) [V0]/01 - EKG.mp3</a></li>

作为一个开始看看如何获​​取每个目录作为嵌套for循环的变量来打印每个目录中的每个mp3,我尝试过这样的事情:

for J in ls `ls -alt|head -30`; do
echo $J
done

但是我遇到了障碍,因为输出会将每个目录名称中的每个空格作为一个新行。任何人有任何想法我怎么能这样做?如何将目录名称(可能包含可能需要转义的字符)作为另一个循环的变量?

2 个答案:

答案 0 :(得分:1)

由于您的文件名包含空格,因此请使用while而不是for。 使用ls -At而不是ls -lat来忽略。和..

ls -At|head -30 | while read line; do
echo "<li><a href=\"#\" data-src=\"music/${line}.mp3\">$line</a></li>"
done

更新:循环多个目录

ls -d */ | while read dir; do
   ls -At ${dir} | head -30 | while read line; do
        echo "<li><a href=\"#\" data-src=\"music/${dir}${line}.mp3\">line</a></li>"
   done
done

答案 1 :(得分:0)

举个例子,让我们从这些mp3文件开始:

$ ls */*mp3
music1/d e.mp3  music1/d.mp3  music2/a b.mp3  music2/a.mp3

有两种安全可靠的方法来处理文件名:一种是使用find,另一种是使用shell内置的globbing。如果操作正确,并且与解析ls不同,这两种方法对于任何和所有文件名都是安全的。这两种方法如下所示。

此外,根据您的最终用法,您可能需要对文件名进行html编码。一种方法是here。如果您将文件名用作网址的一部分,则需要URL encoding

使用find

现在,让我们制作html:

$ find . -iname '*.mp3' -exec bash -c 'printf "<li><a href=\"#\" data-src=\"%s\">%s</a></li>\n" "$1" "$(basename "$1")"' none {} \;
<li><a href="#" data-src="./music2/a b.mp3">a b.mp3</a></li>
<li><a href="#" data-src="./music2/a.mp3">a.mp3</a></li>
<li><a href="#" data-src="./music1/d.mp3">d.mp3</a></li>
<li><a href="#" data-src="./music1/d e.mp3">d e.mp3</a></li>

使用带有extglob的bash

这会在任何深度的所有子目录中找到所有mp3文件的名称,并将它们变成一个html列表:

$ shopt -s extglob
$ for f in **/*.mp3; do printf '<li><a href="#" data-src="%s">%s</a></li>\n' "$f" "$(basename "$f")"; done
<li><a href="#" data-src="music1/d e.mp3">d e.mp3</a></li>
<li><a href="#" data-src="music1/d.mp3">d.mp3</a></li>
<li><a href="#" data-src="music2/a b.mp3">a b.mp3</a></li>
<li><a href="#" data-src="music2/a.mp3">a.mp3</a></li>

或者,写出多行:

shopt -s extglob
for f in **/*.mp3
do 
    printf '<li><a href="#" data-src="%s">%s</a></li>\n' "$f" "$(basename "$f")"
done

解析ls

通常,one should not try to parse ls:除了最简单的文件名之外,它都会失败。例如,让我们创建一个名称包含制表符和换行符的文件:

$ touch $'tab\tc\nd'

以下是ls的输出结果:

$ ls -At tab*
tab?c?d

观察ls错误的名称,用问号?替换标签和换行符。