この質問からUnixを使用した列のコピーと置換
このファイルでのみ機能するソリューションを構築しようとしています。
20070101 10.2317 79.1638 6.0 26.7 20.9 0.8 14.0 98.6
20070102 10.2317 79.1638 5.6 26.5 20.8 1.9 13.6 98.0
20070103 10.2317 79.1638 7.5 27.7 20.8 0.1 15.8 96.4
20070104 10.2317 79.1638 8.1 26.0 19.6 0.0 15.5 94.1
出力を取得します。
01/01/2007 10.2317 79.1638 6.0 26.7 20.9 0.8 14.0 98.6
02/01/2007 10.2317 79.1638 5.6 26.5 20.8 1.9 13.6 98.0
03/01/2007 10.2317 79.1638 7.5 27.7 20.8 0.1 15.8 96.4
04/01/2007 10.2317 79.1638 8.1 26.0 19.6 0.0 15.5 94.1
その他の書類は関係ありません。
だから最初の列を変換された日付に置き換えたいのです。
元のファイルから日付を取得しました。
$ awk '{print $1}' filedate.txt
20070101
20070102
20070103
20070104
その後、以下を使用して日付変換を実行しました。
for i in $(awk '{print $1}' filedate.txt); do date -d "$i" +%d/%m/%Y; done
01/01/2007
02/01/2007
03/01/2007
04/01/2007
ただし、変換された日付値でファイルの最初の列を変更することはできません。私はawk代替()を使ってみましたawk '{$1=$dt}1'
。
for i in $(awk '{print $1}' filedate.txt); do dt=$(date -d "$i" +%d/%m/%Y) && awk '{$1=$dt}1' filedate.txt; done
ただし、ループが含まれているため、出力は必要に応じて出ません。
どうすればいいですかawk
?で同じことができますかsed
?
編集する
他の質問に対するコメントで、次の方法を見ました。sed
sed 's,^\([0-9]\{4\}\)\([0-9]\{2\}\)\([0-9]\{2\}\),\3/\2/\1,'
date
さて、私はコマンドに関連するタスクをどのように実行するのか疑問に思います。
答え1
すでに存在するループを試してみましょう(実際には見ていませんが、うまく機能しているようです)。
for i in $(awk '{print $1}' filedate.txt); do date -d "$i" +%d/%m/%Y; done
それからそれを入れる他の質問に対する私の答え少し修正してください:
for i in $(awk '{print $1}' filedate.txt); do date -d "$i" +%d/%m/%Y; done |
paste - <( cut -d ' ' -f 2- filedate.txt )
結果:
01/01/2007 10.2317 79.1638 6.0 26.7 20.9 0.8 14.0 98.6
02/01/2007 10.2317 79.1638 5.6 26.5 20.8 1.9 13.6 98.0
03/01/2007 10.2317 79.1638 7.5 27.7 20.8 0.1 15.8 96.4
04/01/2007 10.2317 79.1638 8.1 26.0 19.6 0.0 15.5 94.1
ループなしでより短く:
date -f <( cut -d ' ' -f 1 filedate.txt ) +"%d/%m/%Y" |
paste - <( cut -d ' ' -f 2- filedate.txt )
パイプがない場合:
paste <( date -f <( cut -d ' ' -f 1 filedate.txt ) +"%d/%m/%Y" ) \
<( cut -d ' ' -f 2- filedate.txt )
これらすべての例には、明らかにプロセスの置き換えを理解する別のシェルがbash
必要です。また、GNUが必要です。ksh
date
バラより他の質問に対する私の答え仕組みの説明です。
答え2
目的の変換が既存の情報の順序を変更するだけであれば、これを試してみてはいかがでしょうか。
awk '{ $1=sprintf("%02i/%02i/%04i",
substr($1, 7, 2), substr($1, 5, 2), substr($1, 1, 4)) }1' file
最初のフィールドから部分文字列を抽出し、それを最初のフィールドの新しい値に再組み立てし、通常どおり入力行全体を印刷します。 (中括弧の後の別の文字は、1
無条件印刷用の標準Awk慣用語です。)
機械が完全に読むことができる日付を次のように変換すると、後悔する可能性があります。「人が読める」しかしすぐに。
答え3
GNU awk()がある場合は、gawk
コマンド出力を使用して列を置き換えることができます。getline/変数/パイプ形式関数をgetline
呼び出す方法は次のとおりです。date
gawk '{"date +%d/%m/%Y -d" $1 | getline $1} 1' file
ただし、列の日付形式のみを変更したい場合は、組み込み関数mktime
と関数を使用してstrftime
ローカルで変更できます。
gawk '{
d = sprintf("%d %02d %02d 0 0 0", substr($1,1,4), substr($1,5,2), substr($1,7,2));
t = mktime(d);
$1 = strftime("%d/%m/%Y", t);
} 1' file
この場合、単純な文字列操作を使用して目的の変換を実行できます(この方法はすべてのスタイルに適用されますawk
)。
$ mawk '{$1 = sprintf("%02d/%02d/%02d", substr($1,7,2), substr($1,5,2), substr($1,1,4))} 1' file
01/01/2007 10.2317 79.1638 6.0 26.7 20.9 0.8 14.0 98.6
02/01/2007 10.2317 79.1638 5.6 26.5 20.8 1.9 13.6 98.0
03/01/2007 10.2317 79.1638 7.5 27.7 20.8 0.1 15.8 96.4
04/01/2007 10.2317 79.1638 8.1 26.0 19.6 0.0 15.5 94.1
答え4
GNU sedコマンドのe
val修飾子を使用すると、必要に応じて日付を変換できs
ます。date
sed -r 's|(\S+)(.*)|date -d \1 "+%d/%m/%y \2"|e'
置換された式は正しい形式の日付コマンドです。修飾子はe
このコマンドを各行に対して実行し、パターンバッファ(および出力)は各日付コマンドの出力に置き換えられます。