私.csvファイルに次のものが含まれています
Data1|Data2|10/24/2017 8:10:00 AM
3列の日付と時刻の形式を次のように変更したいと思います。
10/24/2017 8:10:00 AM
(12時間)から(20171024 08:10:00
24時間)まで。
-dを使用しないでください
答え1
純粋なawkソリューション(パッキングコマンドなしdate
):
awk -F'|' -vOFS='|' '
function fail() {
printf "Bad data at line %d: ", NR
print
next
}
{
if (split($3, date_time, " ") != 3) fail()
if (split(date_time[1], date, "/") != 3) fail()
if (split(date_time[2], time, ":") != 3) fail()
if (time[1] == 12) time[1] = 0
if (date_time[3] == "PM") time[1] += 12
$3 = sprintf("%.4d%.2d%.2d %.2d:%.2d:%.2d", date[3], date[1], date[2], time[1], time[2], time[3])
print
}'
-F'|'
入力ラインを縦線$1
、、$2
など$3
で割ります。split($3, date_time, " ")
日付/時刻フィールドを日付、時刻、AM/PM インジケータの 3 つの部分に分割します。 3つのブロックがない場合は、エラーメッセージが表示され、対応する行をスキップします。split(date_time[1], date, "/")
日付を月、日、年で割ります。split(date_time[2], time, ":")
時間を時、分、秒で割ります。- たとえば、24時間基準で午前12時42分は00:42です。もちろんPMは12時間を追加します。
sprintf
年、月、日、時、分、秒を再グループ化し、必要に応じて前にゼロを追加します。$3
形式が変更された日付/時刻を使用して入力行を再構成するには、それを割り当ててから印刷します。機能:たとえば、入力フィールドが3つ以上の場合
Data1|Data2|10/24/2017 8:10:00 AM|Data4|Data5
スクリプトはこれらの追加フィールドを保持します。
使用法: いくつかの小さな変更:
- 上記の複数行コマンドを入力し、
}'
最後の行の末尾(後ろ)に処理するファイル名を入力します。もちろん、*.csv
ファイル名に加えて、またはファイル名の代わりにワイルドカード(たとえば)を使用することもできます。 - 上記と同じですが、その後は次のように
}'
言います。<
そしてファイル名。 (これにより、一度に1つのファイルしか処理できません。) - スクリプトファイルを作成します。
- 最初の行はでなければなりません
#!/bin/sh
。 (または必要に応じて、または#!/bin/bash
を使用できます#!/usr/bin/env bash
。これらのさまざまな "she-bang"行と相対的な利点と対応する記号の違いについての議論はこの質問の範囲外です。検索すると、このトピックに関する多くの議論を見つけることができます。 .) - 次に、2行目から上記のコードを入力してください。
- 最後の行の終わり(すぐ後ろ
}'
)に"$@"
(含む引用符)。 - 文書を保存します。私たちはあなたがこのスクリプトを呼び出すと仮定します
gman
。 - タイプ
chmod +x gman
。 - タイプ
./gman
の後にファイル名および/またはワイルドカードのリストを入力するか、<
そしてファイル名。
- 最初の行はでなければなりません
答え2
これを行う1つの方法は次のとおりです(infile
CSVファイルであると仮定)。
#!/bin/bash
IFS='|'
while read data1 data2 datestr
do
newdatestr=$(date -d"$datestr" +"%Y%m%d %T")
printf "%s|%s|%s\n" "$data1" "$data2" "$newdatestr"
done < infile
答え3
そしてAWK
:
アーカイブを保存してくださいa.awk
。
BEGIN{
FS="|"
OFS = FS
}
{
"date -d '"$3"' +'%Y%m%d %T' " | getline l
$3 = l
print $0
}
csvファイルとして実行してください。
awk -f a.awk file.csv
たとえば、出力は次のようになります。
Data1|Data2|20171024 08:10:00
Data1|Data2|20171024 20:10:00
Data1|Data2|20171024 20:10:00
Data1|Data2|20171024 20:14:00
Data1|Data2|20171024 20:14:00
Data1|Data2|20171024 20:11:00
Data1|Data2|20171024 20:10:06
Data1|Data2|20171024 20:10:06
Data1|Data2|20171024 08:10:50
例として:
Data1|Data2|10/24/2017 8:10:00 AM
Data1|Data2|10/24/2017 8:10:00 PM
Data1|Data2|10/24/2017 8:10:00 AM
Data1|Data2|10/24/2017 8:14:00 PM
Data1|Data2|10/24/2017 8:10:00 AM
Data1|Data2|10/24/2017 8:11:00 PM
Data1|Data2|10/24/2017 8:10:06 PM
Data1|Data2|10/24/2017 8:10:00 PM
Data1|Data2|10/24/2017 8:10:50 AM
答え4
プロセスの置き換えは、GNU date
(ではなくdate -d
)と同様のシェルを使用してbash
理解されます。
$ cat file
Data1|Data2|10/24/2017 8:10:00 AM
Data1|Data2|10/24/2017 8:10:00 AM
Data1|Data2|10/24/2017 8:10:00 AM
Data1|Data2|10/24/2017 8:10:00 AM
Data1|Data2|10/24/2017 8:10:00 AM
$ paste -d '|' <( cut -d '|' -f -2 file ) <( date -f <( cut -d '|' -f 3 file ) +'%Y%m%d %T' )
Data1|Data2|20171024 08:10:00
Data1|Data2|20171024 08:10:00
Data1|Data2|20171024 08:10:00
Data1|Data2|20171024 08:10:00
Data1|Data2|20171024 08:10:00
指定されたファイルから区切られた3番目の列を抽出するdate
コマンドから日付を読み取るために呼び出されます。 1行にフォーマットが変更された日付を1つずつ入力して出力します。cut
|
次に、を使用して最初の2つの列で貼り付けますpaste
。
欠点は、ファイルを2回読みますが、一date
度だけ呼び出されることです-d
。