私が所有しているもの
こんにちは、最初の列がエポックで、他の列がいくつかのデータである次のような多くのファイルを想像してみてください。
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
コンテキスト
ファイルは複数のフォルダに分かれて1つの大きなフォルダに保存され、名前は次のようにlogs_swapoff
終わります(このフォルダには触れるべきではない別のsがあります)。_times.csv
csv
ファイルの例:
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;
とても感謝しています:)
ベストアンサー1
列挙ファイル
解析された出力がfind
脆弱。find
変換プログラムを呼び出すことをお勧めします。出力ファイル名を生成するにはパラメータ拡張たとえば、サフィックスを(たとえば)_times.csv
に変更すると_subtracted.csv
十分です。
find logs_swapoff -name '*_times.csv' -exec sh -c '
<"$1" awk "$0" >"${1%_times.csv}_subtracted.csv"
' '…' {} \;
'…'
実行するawkコードです。引用を簡単にするために、シェルの断片の外側に配置しました。
すべてのファイルを変換
ファイルを1行ずつ処理し、各行にいくつかの算術演算を含む単純なテキスト変換を実行する必要があります。これは awk を作業に理想的なツールにします。出力例の唯一の難しさは、最小幅に合わせてソートしたいようですが、最初にファイル全体を読み取って最大幅を決定しない限り、これを行うことはできません。いくつかの余分なスペースがあることに満足している場合は、ファイルを1行ずつ処理できます。
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}
'
したがって、それらを1つにまとめます(コンマバージョン)。
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}
' {} \;