Bash:在循环遍历字符串数组后,不能用空格读出字符串

时间:2011-05-24 21:16:04

标签: arrays bash string for-loop awk

我正在使用循环来读取数组的内容,该数组包含名为“music”的目录层次结构中的所有目录和文件(内容是来自“find”命令的上一输出的字符串)。我们的想法是根据流派,艺术家和标题将“directory_contents”中每个数组元素的完整目录路径分成子串。由于我的音乐目录首先按流派排序,然后按艺术家排序,然后按标题排序,我使用awk抓取每个相关项目,其中分隔符“/”显示。例如,如果在使用find“./Electronic/Squarepusher/My Red Hot Car.aif”之后目录看起来像这样,我会将“Electronic”,“Squarepusher”和“My Red Hot Car”分开,然后分别存储它们。在流派,艺术家和标题的单独数组中。稍后我将对这些数据进行排序,然后将已排序的输出传输到另一个实用程序中,以便在一个漂亮的表中打印所有目录内容(尚未完成此操作)。现在,我只是试图用echo语句查看字符串分隔的结果,并且在大多数情况下它似乎有效。但是,我似乎无法提取包含空格的子串,这是不好的:

-->./Hip-Hop/OutKast/title1.aif<--
Genre:
Hip-Hop
Artist:
OutKast
Title:
title1

-->./Hip-Hop/OutKast/title2.aif<--
Genre:
Hip-Hop
Artist:
OutKast
Title:
title2

-->./Hip-Hop/OutKast/title3.aif<--
Genre:
Hip-Hop
Artist:
OutKast
Title:
title3

-->./Jazz/John<--
Genre:
Jazz
Artist:
John
Title:


-->Coltrane/title1.aif<--
Genre:
title1.aif
Artist:

Title:

正如您所看到的,当循环读入字符串“John Coltrane”时,它将空格视为分隔符,并将“John”之后的所有内容视为不同的文件名。我尝试在bray手册中的“Arrays”部分以及其他帖子中查找解决方案,但找不到适合我特定问题的解决方案(抱歉)。如果有人有想法,他们将不胜感激。有问题的代码出现在下面,在for循环中(我没有发布整个脚本,因为它非常冗长,但如果需要的话请让我):

#more before this...

#declare variables                                                                                                      
declare -a genre_list                                                                                                   
declare -a title_list                                                                                                   
declare -a artist_list                                                                                                  
declare -a directory_contents                                                                                           


#populate directory with contents                                                                                       
cd $directory                                                                                                           
directory_contents=$(find .  -mindepth 1 -type f)                                                                       
cd ..                                                                                                                   


for music_file in ${directory_contents[*]}; do                                                                          
    if [[ $DEBUG = "true" ]] ; then                                                                                     
        echo "-->$music_file<--"                                                                                        
    fi                                                                                                                  

    echo "Genre:"                                                                                                       
    echo $music_file | awk -F"/" '{print $2}'                                                              
    echo "Artist:"                                                                                                      
    echo $music_file | awk -F"/" '{print $3}'                                                               
    echo "Title:"                                                                                                       
    echo $music_file | awk -F"/" '{print $4}' | awk -F"." '{print $1}'                                     
    echo ""                                                                                                             
done   

4 个答案:

答案 0 :(得分:2)

为什么不简单地用一行来做:

cd $directory && \
find .  -mindepth 3 -maxdepth 3 -type f | \ 
awk -F'/' '{split($4,A,".aif"); printf "Genre: %s\nArtist: %s\nTitle: %s\n\n",$2,$3,A[1];}'

更新: (从标题部分删除 .aif

答案 1 :(得分:1)

如果可以,您应该使用Perl执行此任务:

#! /usr/bin/perl

foreach my $fname (<*/*/*>) {
  next unless -f $fname;
  next unless $fname =~ m"^([^/]+)/([^/]+)/([^/.]+)\.\w+$";
  my ($genre, $artist, $title) = ($1, $2, $3);
  printf("Genre: %s\nArtist: %s\nTitle: %s\n\n", $genre, $artist, $title);
}

它比shell快,更简单,并且不受文件名中的空白的影响。

答案 2 :(得分:1)

MUSICDIR="/some/path"
cd "$MUSICDIR"

find  . -type f -print | (IFS=/;while read dot genre artist title
do
    echo =$genre= =$artist= =$title=
done)

答案 3 :(得分:0)

您可以尝试设置bash使用的分隔符。也许是换行符?

IFS=\n