2016-03-11 98 views
0

下面是一個示例的數據集(10個COLS,2行):bash的for循環不循環(AWK時,bash,LINUX)

8 1 4 10 7 9 2 3 6 5 
0.001475 10.001 20.25 30.5 40.75 51 61.25 71.5 81.75 92

我想輸出十個文件爲每個數據集。每個文件將包含第二行中的唯一值,並且文件名將包含第一行中相應列的值。

(例如:含有0.001475一個文件,叫foo_bar_8.1D

見下面我的代碼,用於使用下列數據集:

 
OrderTimesKC_voxel_tuning_1.txt 
OrderTimesKC_voxel_tuning_2.txt 
OrderTimesKC_voxel_tuning_3.txt 
OrderTimesKC_voxel_tuning_4.txt 
OrderTimesKC_voxel_tuning_5.txt

腳本:

subj='KC' 
     for j in {1..5}; do 
      for x in {1..10}; do 
       a=$(awk 'FNR == 1 {print $"$x"}' OrderTimes"$subj"_voxel_tuning_"$j".txt) #a == row 1, column x 
       b=$(awk 'FNR == 2 {print $"$x"}' OrderTimes"$subj"_voxel_tuning_"$j".txt) #b == row 2, column x 
       echo $b > voxTim_"$subj"_"$j"_"$a".1D 
      done 
     done 

的目前輸出的文件有:

voxTim_KC_1_8?1?4?10?7?9?2?3?6?5.1D 
voxTim_KC_2_8?1?4?10?7?9?2?3?6?5.1D 
voxTim_KC_3_8?1?4?10?7?9?2?3?6?5.1D 
voxTim_KC_4_8?1?4?10?7?9?2?3?6?5.1D 
voxTim_KC_5_8?1?4?10?7?9?2?3?6?5.1D

這些包含每個文件十個值,表明它沒有正確循環。

我要的是:

 
voxTim_KC_1_1.1D, voxTim_KC_1_2.1D, voxTim_KC_1_3.1D..... 
voxTim_KC_2_1.1D, voxTim_KC_2_2.1D, voxTim_KC_2_3.1D..... 
and so on..

謝謝!

+2

你的循環是不是做了什麼你覺得是因爲你與外殼混淆AWK和另外誤解shell引用規則,但更重要的是不管它是你正在嘗試做的,你的做法是錯誤解釋你正在嘗試做什麼以及一些具體的,可測試的樣本輸入和期望的輸出,我們可以幫助你。如果/當你得到一個答案,告訴你如何讓現有的腳本產生你期望的輸出,請記住這是錯誤的方法。 –

回答

1

awk來救援!

您可以更有效地利用awk,例如這個腳本會做兩個值的提取從每個輸入文件,並創建10(或實際列數)的文件與數據

$ awk 'FNR==1{c++; n=split($0,r1); next} 
     FNR==2{split($0,r2); 
       for(i=1;i<=n;i++) print r2[i] > "file."c"."r1[i]".1D"}' input1 input2 

將創建給定input1和input2文件的一組文件。您可以將其用作模板並擺脫for循環。

例如

$ tail -n 2 * 
==> input1 <== 
8 1 4 10 7 9 2 3 6 5 
0.001475 10.001 20.25 30.5 40.75 51 61.25 71.5 81.75 92 

==> input2 <== 
98 91 94 910 97 99 92 93 96 95 
0.001475 10.001 20.25 30.5 40.75 51 61.25 71.5 81.75 92 

運行腳本

$ ls 
file.1.1.1D file.1.2.1D file.1.4.1D file.1.6.1D file.1.8.1D file.2.91.1D file.2.92.1D file.2.94.1D file.2.96.1D file.2.98.1D input1 
file.1.10.1D file.1.3.1D file.1.5.1D file.1.7.1D file.1.9.1D file.2.910.1D file.2.93.1D file.2.95.1D file.2.97.1D file.2.99.1D input2 

和內容

$ tail -n 2 file.1* 
==> file.1.1.1D <== 
10.001 

==> file.1.10.1D <== 
30.5 

==> file.1.2.1D <== 
61.25 

==> file.1.3.1D <== 
71.5 

==> file.1.4.1D <== 
20.25 

etc... 

實際上後,您可以簡單地把它進一步

$ awk 'FNR==1{c++; n=split($0,r1)} 
     FNR==2{for(i=1;i<=n;i++) print $i > ("file."c"."r1[i]".1D")}' input1 input2 
+1

對,好點。固定。 – karakfa

1

只需使用bash:

subj=KC 
for j in {1..5}; do 
    { 
     read -ra a  # read the 1st line into array 'a' 
     read -ra b  # read the 2nd line into array 'b' 
     for i in {0..9}; do 
      echo "${b[i]}" > "voxTim_${subj}_${j}_${a[i]}.1D" 
     done 
    } < "OrderTimes${subj}_voxel_tuning_${j}.txt" 
done 
+0

'echo'在這裏可能沒問題,但'echo「$ ...」'在某些情況下可能會做錯事。 'printf'%s \ n'「$ ...」'始終安全。 – pjh

+0

什麼不對?什麼情況? –

+0

如果'x = -n'然後'echo「$ x」'只會打印'printf'%s \ n'「$ x」'打印'-n'。 '-e'和'-E'也是一樣。另外,如果設置了'xpg_echo',則參數中的反斜槓轉義序列將被展開。 – pjh