2013-11-23 24 views
0

預期結果的描述:組合時間/數據的矢量到文本矩陣以特定的順序

我的輸入由幾十個文件夾的與名稱等這些:

「FD = 6944.88450 7244.2 4049.1 0.0250"

每個文件夾中包含的文本範圍文件各包含一個時間和一個數據矢量,像這樣:

0.0032771032 0.0000000 
0.023277102 0.0000000 
0.063277103 0.0000000 
0.12327710 0.0000000 
1.0032771 0.0000000 
2.0032771 0.0000000 
3.0032771 0.0000000 
4.0032768 0.0000000 
5.0032768 0.0000000 

其中左列是時間,右邊是數據向量。每個數據文件都有一個唯一的名稱(注意:它們在每個文件夾中重複的文件夾中的唯一名稱)。我需要遍歷文件夾並根據文件的名稱以指定的順序讀入數據向量。預期的輸出是這樣的:

[時間矢量] [數據 - 矢量-1] [數據 - 矢量-2] [數據 - 矢量-3] ... [數據 - 矢量-20]

產生具有21列的矩陣。該文件夾包含的文件多於矩陣將包含矢量的文件,因此一些文件將不被使用。時間向量或列對文件夾內的所有文件都是相同的。什麼我試圖

說明:

我嘗試了慶典和awk的混合物。

首先,我需要遍歷文件夾中的所有文件,並找到文件名,我應該可以使用這些文件名進行標準字符串比較,以便我可以按所需順序讀取文件。

要檢查這個這個功能,我介紹了下面的代碼:

#!/bin/bash 
cd /the/correct/Directory/DataOutput 

# Stringlist of Filenames 
TIME='TIME.dat' 
MeltMass='MeltMass.dat' 
EjectedMass='EjectedMass.dat' 

# Note: blank (=> contained in FILES) is by standard one of the field separators => end of file name assumed even with suppression operator "\" 
Reassging new value to list of field separators IFS 
SAVEIFS=$IFS 
IFS=$(echo -en "\n\b") 
# set me 
FILES=./FD\=6944.88450\ 7244.2\ 4049.1\ 0.0250/* 
for f in $FILES 
do 
    # echo "$f" 
    filename=$(basename $f) 
    echo $filename 

    if [ "$filename"=="$TIME" ]; 
    then 
    echo $filename 
    echo $TIME 
    elif [[ "$filename"=="$MeltMass" ]]; 
    then 
    echo $filename 
    echo $MeltMass 
    elif [ "$filename"=="$EjectedMass" ]; 
    then 
    echo $filename 
    echo $EjectedMass 
    elif [ "$filename"=='DowncomerLevel.dat' ]; 
    then 
    echo $filename 
    echo 'DowncomerLevel.dat' 
    elif [ "$filename"=='MaxTemp_Core.dat' ]; 
    then 
    echo $filename 
    echo 'MaxTemp_Core.dat' 
    else 
    echo $filename 

    echo 'Not found' 
    fi 

done 
# restore $IFS 
IFS=$SAVEIFS 

回聲$文件名返回目錄中的文件列表。配置中的if-then-else無法按預期工作。它卡上的第一項(總是返回):

echo $filename 
    echo $TIME 

不管什麼文件名實際上包含。我嘗試使用陣列的替代形式:

files=(./FD\=6944.88450\ 7244.2\ 4049.1\ 0.0250/*.dat) 
for file in "${files[@]}" 
do 
    filename="${file##*/}" 
# filenameWithoutExtension="${filename%.*}" 
    echo "$filenameWithoutExtension" 

    if [ "$filename"=="$TIME" ]; 
    then 
    echo $filename 
    echo $TIME 
    elif [[ "$filename"=="$MeltMass" ]]; 
    then 
    echo $filename 
    echo $MeltMass 
    elif [ "$filename"=="$EjectedMass" ]; 
    then 
    echo $filename 
    echo $EjectedMass 
    elif [ "$filename"=='DowncomerLevel.dat' ]; 
    then 
    echo $filename 
    echo 'DowncomerLevel.dat' 
    elif [ "$filename"=='MaxTemp_Core.dat' ]; 
    then 
    echo $filename 
    echo 'MaxTemp_Core.dat' 
    else 
    echo $filename 

    echo 'Not found' 
    fi 

done 

但結果相同。任何人都知道這個問題的原因是什麼以及如何解決這個問題?

問候,

HobbsTuna

+0

文件名中的空格是問題。唯一的解決方法是確保任何常量文件名字符串(無變量)被單引號包圍,並且任何文件名變量都由雙引號括起來。一個示例問題是:FILES = ./ FD \ = 6944.88450 \ 7244.2 \ 4049.1 \ 0.0250/* - 您的文件名是變量FILES將填充空格,因此所有文件名都被破壞。 –

+0

我不確定我是否理解。首先我認爲改變IFS會照顧空白。其次,實際比較的文件名不包含任何空格(例如Time.dat,MeltMass.dat,MeltEject.dat等),並且通過echo $ filename正確顯示。這是我在比較中使用的部分,這是不工作的部分,所以我不確定我是否理解你的解釋。 – HobbsTunaSandwich

回答

2

第1步 - 找到文件的目錄(folders是Windows下的術語)的列表。

試試這個:

find "FD=6944.88450 7244.2 4049.1 0.0250" -type f -print | 
while IFS= read -r dirFile 
do 
    filename=$(basename "$dirFile") 
    printf 'filename="%s"\n' "$filename" 

    filenameWithoutExtension=$(basename "$dirFile" ".dat") 
    printf 'filenameWithoutExtension="%s"\n' "$filenameWithoutExtension" 
done 

爲你做這項工作?

如果是這樣 - 接下來要做什麼?到目前爲止,您告訴我們您需要處理一些(但不是所有)文件,並且按照某種順序處理,但是AFAIK您沒有告訴我們具體哪些文件或者哪些文件或者處理涉及什麼。

根據您的評論下面,我想你只是有一個特定的文件列表,你想按特定的順序,如果它們存在。下面的內容應該讓你在正確的軌道上。

這裏我們想按照這個順序處理文件a,b和c(如果它們存在的話)。 a和c存在,b不:

$ cat a 
3 foo 
7 bar 
$ 
$ cat b 
cat: b: No such file or directory 
$ 
$ cat c 
3 other 
7 stuff 
$ 
$ cat tst.awk 
BEGIN { 
    split("a b c",files) 
    for (i=1; i in files; i++) { 
     file = files[i] 
     if ((getline tmp < file) > 0) { 
      # file exists and is not empty 
      ARGV[ARGC++] = file 
     } 
     close(file) 
    } 
} 

{ 
    time = $1 
    data = $2 

    if (!seen[time]++) { 
     times[++numTimes] = time 
    } 

    time2data[time] = time2data[time] (NR==FNR ? "" : OFS) data 
} 

END { 
    for (i=1; i<=numTimes; i++) { 
     time = times[i] 
     print time, time2data[time] 
    } 
} 
$ 
$ awk -f tst.awk 
3 foo other 
7 bar stuff 

有意義嗎?

+0

它確實有效,它返回所有文件的列表,但引用的代碼示例也可以這樣做。我很抱歉不清楚。實際的問題是文件列表按字母順序排列。就像這樣:'ADS_TimeDelay AvgDebTempLP CoreDebris_MCRP Core_Debris_mSS CoreDebris_SS CoreDebris_SSOX CoreDebris_UO2 CoreDebris_ZR CoreDebris_ZrO2 DowncomerLevel ECCS_MassFlow EjectedMass HydMassCont Keff LPDebris_MCRP LPDebris_SS LPDebris_SSOX LPDebris_UO2 LPDebris_ZR LPDebris_ZrO2 MaxTemp_Core MaxTemp_LP MeltMass SS_Debris_LP SSO2_Debris_LP ... ZrO2_Debris_LP' – HobbsTunaSandwich

+0

矩陣表中的順序無關,與字母順序排列,S我試圖迫使代碼目錄中的一個特定的輸入文件的讀取(例如「CoreDebris_UO2」第一個)。所以我試圖找到每個字符串比較的「CoreDebris_UO2」,如果是這樣的話,從相同名稱的文件中讀取到一個新的輸入文件,最終會變成矩陣。你有其他方法嗎? – HobbsTunaSandwich

+0

你是說你只是有一個特定文件名的列表,如果它們存在,那麼你需要按特定的順序解析它們? –