我有(幾個)大文本檔案,我想從中提取一些值來創建一個包含所有這些值的 csv 檔案。
我當前的解決方案是對 sed 進行一些不同的呼叫,從中保存值,然后使用 python 腳本將不同檔案中的資料組合到單個 csv 檔案中。但是,這很慢,我想加快速度。
我們稱之為檔案的my_file_1.txt結構看起來像這樣
lines I don't need
start value 123
lines I don't need
epoch 1
...
lines I don't need
epoch N
stop value 234
lines I don't need
start value 345
lines I don't need
epoch 1
...
lines I don't need
epoch M
stop value 456
...
我想構建類似的東西
file,start,stop,epoch,run
my_file1,123,234,N,1
my_file1,345,456,N,2
...
我怎樣才能得到我想要的結果?只要我不需要安裝新的東西并且速度相當快,它就不必是 Sed 或 Awk。
我對awk沒有任何經驗。使用 sed 我最好的猜測是
filename=$1
echo 'file,start,stop,epoch,run' > my_data.csv
sed -n '
s/.*start value \([0-9]\ \).*/'"$filename"',\1,/
h
$!N
/.*epoch \([0-9]\ \).*\n.*stop value\([0-9]\ \)/{
s/\2,\1/
!s/.*start value \([0-9]\ \).*/'"$filename"',\1,/
D
T
G
P
' $filename | sed -z 's/,\n/,/' >> my_data.csv
然后處理沒有得到運行號。此外,這并不完全正確,因為它N會吞噬一些導致錯誤結果的“起始值”行。感覺使用 awk 可以更輕松地完成。
它類似于8992158但我不能使用該模式,而且我知道的 awk 太少而無法重寫它。
uj5u.com熱心網友回復:
目前尚不清楚如何從您提供的輸入中準確獲得您提供的輸出,但這可能是您正在嘗試做的事情(在每個 Unix 機器上的任何 shell 中使用任何 awk):
$ cat tst.awk
BEGIN {
OFS = ","
print "file", "start", "stop", "epoch", "run"
}
{ f[$1] = $NF }
$1 == "stop" {
print FILENAME, f["start"], f["stop"], f["epoch"], run
delete f
}
$ awk -f tst.awk my_file_1.txt
file,start,stop,epoch,run
my_file_1.txt,123,234,N,1
my_file_1.txt,345,456,M,2
uj5u.com熱心網友回復:
awk的基本結構是:
- 從輸入中讀取一條記錄(默認情況下一條記錄是一行)
- 評估條件
- 應用動作
記錄被分成多個欄位(默認基于空格作為分隔符)。這些欄位由它們的位置參考,從 1 開始。$1 是第一個欄位,$2 是第二個。最后一個欄位由名為“欄位數”的變數 NF 參考。$NF 是最后一個欄位,$(NF-1) 是倒數第二個欄位,以此類推。
在讀取任何輸入檔案之前將執行“BEGIN”部分,它可用于初始化變數(隱式初始化為 0)。
BEGIN {
counter = 1
OFS = "," # This is the output field separator used by the print statement
print "file", "start", "stop", "epoch", "run" # Print the header line
}
/start value/ {
startValue = $NF # when a line contains "start value" store the last field as startValue
}
/epoch/ {
epoch = $NF
}
/stop value/ {
stopValue = $NF
# we have everything to print our line
print FILENAME, startValue, stopValue, epoch, counter
counter = counter 1
startValue = "" # clear variables so they aren't maintained through the next iteration
epoch = ""
}
將其保存為 processor.awk 并呼叫為:
awk -f processor.awk my_file_1.txt my_file_2.txt my_file_3.txt > output.csv
uj5u.com熱心網友回復:
這可能對您有用(GNU sed):
sed -nE '1{x;s/^/file,start,stop,epock,run/p;s/.*/0/;x}
/^start value/{:a;N;/\nstop value/!ba;x
s/.*/expr & 1/e;x;G;F
s/^start value (\S ).*\nepoch (\S )\nstop value (\S ).*\n(\S )/,\1,\3,\2,\4/p}' file |
sed '1!N;s/\n//'
該解決方案包含對 sed 的兩次呼叫,第一次格式化除檔案名之外的所有檔案名,第二次將檔案名嵌入到 csv 檔案中。
格式化第一行的標題行并填充運行編號。
收集 和 之間的start value線stop value。
增加運行號,將其附加到當前行并輸出檔案名。這將每條記錄列印兩行,第一行是檔案名,第二行是 csv 檔案的其余部分。
在第二次 sed 呼叫中,一次讀取兩行(第一行除外)并洗掉它們之間的換行符,格式化 csv 檔案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/455969.html
上一篇:重擊|變數中的變數
