2016-03-06 62 views
-1

我有,例如10個數據文件I01.txt一個文件夾,...,I10.txt。每個文件,使用命令/a.out執行時,給了我五個輸出文件,即f1.txtf2.txt,... f5.txt重定向結果的文件不同的變量文件名

我寫了一個簡單的bash程序中使用的命令

./ cosima_peaks_444_temp_muuttuva -args > $counter-res.txt. 

以此來執行所有的文件,並保存在屏幕上打印輸出到一個變量文件,我能夠節省屏幕上的輸出到文件。但是五個文件f1f5被更改爲存儲最後文件運行的結果,在這種情況下爲I10,並且前九個文件的結果丟失。

所以我想每個I*.txt文件的輸出(f1 ... f5)保存到AA不同的文件,例如,當程序執行I01.txt,使用./a.out它存儲的文件的輸出

f1>var1-f1.txt , f2>var1-f2.txt... f5 > var1-f5.txt 

然後重複相同的I02f1>var2-f1.txt ...)。

#!/bin/bash 

# echo "for looping over all the .txt files" 
echo -e "Enter the name of the file or q to quit " 
read dir 
if [[ $dir = q ]] 
then   
    exit 
fi 

filename="$dir*.txt" 
counter=0 

if [[ $dir == I ]] 
then 
    for f in $filename ; do 
     echo "output of $filename" 
     ((counter ++)) 
     ./cosima_peaks_444_temp_muuttuva $f -m202.75 -c1 -ng0.5 -a0.0 -b1.0 -e1.0 -lg > $counter-res.txt 
     echo "counter $counter" 
    done 
fi 
+0

你需要改變'a.out',我以爲是用C寫它不應該是一個困難的工作,以改變C,但是除此之外,bash無法判斷C程序在任何時候正在處理哪個文件。 – cdarke

+0

是'a.out'簡單地讀取目錄的內容(例如用'opendir'或'scandir'),或者你是否傳遞''l01.txt','l02.txt'等等作爲參數該程序? –

+0

這裏./cosima_peaks_444_muuttuva是a.out。並且可執行文件是用Fortran 90編寫的。 –

回答

0

如果我知道你要的文件l01.txtl02.txt,通...到a.out併爲a.out每次執行保存輸出到像f01.txt一個單獨的文件,f02.txt,......,那麼你可以使用一個簡短的腳本讀取名爲l*.txt目錄中的每個文件和價值傳遞給a.out輸出重定向到一個文件fN.txt(分別爲N是在lN.txt文件名相同的數字。)這假設你在每個文件名傳遞給a.outa.out不會自動讀取整個目錄。

for i in l*.txt; do 
    num=$(sed 's/^l\(.*\)[.]txt/\1/' <<<"$i") 
    ./a.out "$i" > "f${num}.txt" 
done 

注:'s/(lowercase L) ... /\one..'

注:如果你不想從文件名相同N(憑藉其領先的'0'),那麼你可以修剪從領先'0'輸出文件名的值爲N

(你可以使用counter正如你在後期編輯所顯示的,但你必須在使用的循環,除非你明確地對它們進行排序文件名的排序順序不保證)

注:,這假設NO spaces或嵌入newline或文件名中的其他奇數字符。如果您的lN.txt名稱可能具有奇數字符或空格,則將while循環與find一起送入可避免奇怪的字符問題。


隨着f1 - f5創建的每個運行

你知道輸出文件名格式,所以你可以測試現有的文件名存在並設置前綴後綴提供唯一的名稱。例如,如果你第一遍創建文件名'pass1-f01.txt''pass1-f02.txt',那麼您可以檢查該模式(在幾個方面),並增加你的'passN'前綴要求:

for f in "$filename"; do 
    num=$(sed 's/l*\(.*\)[.]txt/\1/' <<<"$f") 
    count=$(sed 's/^0*//' <<<"$num") 
    while [ -f "pass${count}-f${num}.txt" ]; do 
     ((count++)) 
    done 
    ./a.out "$f" > "pass${count}-f${num}.txt" 
done 

給一個嘗試,讓我知道這是否並不接近你所需要的。

注:使用herestring<<<)是慶典專用,如果你需要一個便攜式解決方案,管道echo "$var"sed輸出,如count=$(echo "$num" | sed 's/^0*//')

+0

我很抱歉不明確。當我將I01.txt傳遞給a.out時,它給了我五個文件,即f1..f5.txt。當我通過a.out傳遞I02.txt時,f1..f5文件中的結果將被替換。所以我基本上想要運行I01並將五個輸出文件f1..f5保存爲五個單獨的文件,如var1 .... var1-f5,以便在碰巧運行I02時不會改變... I10文件 –

+0

OK ,現在我明白你想要做什麼了,讓我思考一下,然後編輯答案。 –

+0

這很適合David。謝謝。 –

0

我猜你有這個a.out二進制文件的源代碼。如果是這樣,我會修改它,以便它輸出到幾個文件而不是幾個文件。然後你可以使用重定向非常乾淨地解決這個問題:

./a.out 3> fileX.1 4> fileX.2 5> fileX.3 

等等你想要輸出的每個文件。寫入文件或寫入(重定向)fd在大多數程序中都是相同的(值得注意的例外:內存映射I/O,但通常不用於此類腳本 - 查找mmap調用)

請注意,這不是非常深奧,但是一個非常有名的技術常常用於將輸出(stdout,fd = 1)與錯誤(stderr,fd = 2)分開。

0

我用function myprog替換了cosima_peaks_444_temp_muuttuva。 的OP要求更多的解釋,所以我把很多評論:

# This function makes 5 output files for testing the construction 
function myprog { 
    # Fill the test output file f1.txt with the input filename and a datestamp 
    echo "Output run $1 on $(date)" > f1.txt 
    # The original prog makes 5 output files, so I copy the new testfile 4 times 
    cp f1.txt f2.txt 
    cp f1.txt f3.txt 
    cp f1.txt f4.txt 
    cp f1.txt f5.txt 
} 

# Use the number in the inputfile for making a unique filename and move the output 
function move_output { 
    # The parameter ${1} is filled with something like I03.txt 
    # You can get the number with a sed action, but it is more efficient to use 
    # bash functions, even in 2 steps. 
    # First step: Cut off from the end as much as possiple (%%) starting with a dot. 
    Inumber=${1%%.*} 
    # Step 2: Remove the I from the Inumber (that is filled with something like "I03"). 
    number=${Inumber#I} 
    # Move all outputfiles from last run 
    for outputfile in f*txt; do 
     # Put the number in front of the original name 
     mv "${outputfile}" "${number}_${outputfile}" 
    done 
} 

# Start the main processing. You will perform the same logic for all input files, 
# so make a loop for all files. I guess all input files start with an "I", 
# followed by 2 characters (a number), and .txt. No need to use ls for listing those. 

for input in I??.txt; do 
    # Call the dummy prog above with the name of the first input file as a parameter 
    myprog "${input}" 
    # Now finally the show starts. 
    # Call the function for moving the 5 outputfiles to another name. 
    move_output "${input}" 
done 
+0

嗨,你能解釋一下上面的細分。謝謝。 –

+0

@Carlton:查看答案。 –

相關問題