Bash
將一列epochs轉換為從0開始的時間列
是)我有的
嗨,想像一下很多這樣的文件,其中第一列是紀元,其他列是一些數據:
1000333,34,1 1001456,56,0 1005356,34,2
我需要的
我需要將它們轉換為:
0,34,1 1123,56,0 5023,34,2
上述第一列編號來自:
1000333 - 1000333 = 0 1001456 - 1000333 = 1123 1005356 - 1000333 = 5023
語境
這些文件在幾個文件夾中放入一個名為 的大文件夾
logs_swapoff
中,它們以_times.csv
(這些文件夾中還有另一個csv
s 不能碰)結尾。文件範例:
logs_swapoff/folder1/modifyMe_times.csv logs_swapoff/folder1/dontTouchMe_cores.csv logs_swapoff/folder2/modifyMeToo_times.csv
我打算在 bash 中使用這個循環,但我不知道如何完成任務本身。
for filename in $(find logs_swapoff/* -name '*_times.csv') ; do # filename without extension (to write the output with a similar name?) fname=$(dirname $filename`"/"`basename -s .csv $filename); ????? done;
多謝你們 :)
列舉文件
解析的輸出
find
是脆弱的。最好find
呼叫轉換程序。要生成輸出文件名,一個簡單的參數擴展就足以將後綴_times.csv
改為_subtracted.csv
(例如)。find logs_swapoff -name '*_times.csv' -exec sh -c ' <"$1" awk "$0" >"${1%_times.csv}_subtracted.csv" ' '…' {} \;
這
'…'
是要執行的 awk 程式碼。我把它放在 shell 片段之外以簡化引用。轉換每個文件
您需要逐行處理文件,並在每一行上進行涉及一些算術的簡單文本轉換。這使得 awk 成為這項工作的理想工具。範例輸出的唯一困難是您似乎想要對齊最小寬度;如果不首先讀取整個文件以確定最大寬度,就無法做到這一點。如果您對一些額外的空格感到滿意,您可以逐行處理文件。
awk ' NR==1 {start = $1} {n = $1 - start; sub(/^ *[0-9]+/, ""); printf "%6d", n; print} '
說明:在第一行,將
start
變數設置為第一個數字。然後,在每一行上,start
從第一個數字中減去 的值,然後去掉第一個數字。列印減法的結果(用空格填充到 6 個字元)和該行的其餘部分。此程式碼假定第一個數字後總是有空格。如果不是這種情況,您可以進行更精確的匹配。
awk ' NR==1 {match(/[0-9]+/); start = substr(RSTART, RLENGTH)} match(/[0-9]+/) {n = substr(RSTART, RLENGTH) - start; sub(/ *[0-9]+/, ""); printf "%6d", n; print} '
如果欄位是逗號分隔的並且沒有空格需要擔心,請將逗號聲明為欄位分隔符。然後,您可以簡單地用更新的值替換第一個欄位。
awk -F, ' NR==1 {start = $1} {$1 = $1 - start; print} '
所以把它們放在一起(逗號版本):
find logs_swapoff -name '*_times.csv' -exec sh -c ' <"$1" awk -F, "$0" >"${1%_times.csv}_subtracted.csv" ' ' NR==1 {start = $1} {$1 = $1 - start; print} ' {} \;