簡體   English   中英

Bash:在遍歷字符串數組后無法讀出帶空格的字符串

[英]Bash: cant' read out strings with spaces after looping through array of strings

我正在使用循環來讀取數組的內容,該數組包含名為“音樂”的目錄層次結構中的所有目錄和文件(內容是來自“查找”命令的先前 output 的字符串)。 這個想法是根據流派、藝術家和標題將“directory_contents”中每個數組元素的完整目錄路徑分成子字符串。 由於我的音樂目錄首先按流派排序,然后按藝術家排序,然后按標題排序,因此我使用 awk 抓取每個相關項目,其中分隔符“/”出現。 例如,如果使用 find "./Electronic/Squarepusher/My Red Hot Car.aif" 后目錄看起來像這樣,我將把 "Electronic"、"Squarepusher" 和 "My Red Hot Car" 分開,然后分別存儲在單獨的 arrays 中用於流派、藝術家和標題。 稍后我將對這些數據進行排序,然后將 pipe 排序后的 output 放入另一個實用程序中,以在一個漂亮的表中打印所有目錄內容(還沒有這樣做)。 目前,我只是嘗試使用 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”之后的所有內容視為不同的文件名。 我嘗試在 bash 手冊中的“陣列”部分以及此處的其他帖子中尋找解決方案,但找不到適合我的特定問題的解決方案(抱歉)。 如果有人有想法,他們將不勝感激。 有問題的代碼出現在下面的 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   

你為什么不簡單地在單行中做:

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

如果可以,您應該使用 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 更快、更簡單,並且不受文件名中的空格的影響。

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

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

您可以嘗試設置 bash 使用的分隔符。 也許換行符?

IFS=\n

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM