awk sed ifステートメント


9

「。」がある場合、最初に0を追加しようとしています。その行の2番目の文字。これら2つを組み合わせることができませんでした。

awk '{ print substr( $0, 2, 1 ) }' file.txt 

2番目の文字を表示

sed -ie "s/.\{0\}/0/" file.txt

先頭にゼロを追加します。

「2番目の文字がドットの場合」があるはずです。

サンプルファイル:

1.02.2017 23:40:00
10.02.2017 23:40:00

最後の:

01.02.2017 23:40:00
10.02.2017 23:40:00

回答:


12

sedまたはのいずれかを使用してawk、問題を完全に解決します。


sed

$ sed 's/^.\./0&/' file.txt

場合&、置換コマンド(の交換部品で発生しs)、コマンドのパターンの一部に一致する入力ラインの一部に拡張されます。

正規表現と^.\.は、「^)任意の文字(.)で始まり、その後にリテラルドット(\.)が続くすべての行に一致する」という意味です。

行がの1.02.2017 23:40:00場合、パターンは一致し、行の先頭で1.置き換えられ01.ます。


awk

awk質問の部分的なコードに基づいて構築しています...

前述のように、これは入力の各行の2番目の文字を出力します。

$ awk '{ print substr($0, 2, 1) }' file.txt

substr($0, 2, 1)2番目の文字を返すという事実を使用して、それを条件として使用できます。

$ awk 'substr($0, 2, 1) == "." { ... }' file.txt

入るの{ ... }$0、前の条件が真の場合、現在の行の内容であるにゼロを付加するコードです。

$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 }' file.txt

次に、すべての行が印刷されることを確認する必要があります。

$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 } { print }' file.txt

substr($0, 2, 1) == "."もちろん、条件も正規表現に変更できます(sedソリューションで使用したものとまったく同じ式を使用します)。

$ awk '/^.\./ { $0 = "0" $0 } { print }' file.txt

「短いほど良い」と考える人は、

$ awk '/^.\./ { $0 = "0" $0 } 1' file.txt

(そしておそらくほとんどのスペースを削除します。awk '/^.\./{$0="0"$0}1' file.txt


1
+1最後のAWKの例またはsedの例は、これを行う正しい方法です。わかりやすくするために、どちらか一方のみになることに注意してください。
追って通知があるまで一時停止。

私の意見では、「正しい」アプローチ(スペースをいじらない、とにかく軽量)が最終バージョンですsed 's/^.\./0&/' file.txt。私はあなたがこの答えの最初にそれを置くべきだと思います。それでも、+ 1。
ワイルドカード

1
@ワイルドカード私たちは喜んで目指しています。
クサラナンダ

5

sedを使用:

sed -e "/^.\./s/^/0/" file.txt 

パターン/^.\./は、行の先頭で任意の文字とリテラルドットを検索し^、一致する場合は、sその行の先頭をゼロに置き換えて、事実上ゼロを先頭に追加します。

sedエクスプレスインs/.\{0\}/0/はやや奇妙で、0個以上のコピーに一致し、ゼロに置き換わります。もちろん、パターンは文字列のすべての位置で一致しますs///が、最初の一致のみを置き換えるため、意図したとおりに機能します。ただし、趣のある方法で行うことができます。


または、awkを使用すると、同様の正規表現で行を一致させることができますが、次のように使用できますsubstr

awk 'substr($0, 2, 1) == "." {$0 = "0" $0} 1' file.txt 

最初に、2番目の文字がドットかどうかをテストし、ドットの場合は行の先頭にゼロを追加します。最後のものは、変更後に行を印刷するというデフォルトのアクションを呼び出します。


4

あなたはawkとsedを言ったが、日付をフォーマットしようとしているようで、そのためにdateコマンドを使用する。例えば:

echo '1.2.2017 23:40:00' | sed 's/\./\//g' | xargs -0 date '+%m.%d.%Y %T' -d

出力されます

01.02.2017 23:40:00

sed真ん中のコマンドは、への入力のためにピリオドをスラッシュに変更しますdate -d。形式オプションを使用すると、ほぼすべての形式で出力できます。%m特定の意志ゼロパッドの月、あなたがやろうとしているように、それが思われるものです。

クサラナンダが指摘するように:

さらにコンパクト(GNU日付とBash): date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'


2
ナイスキャッチ!さらにコンパクトに(GNUの日付とバッシュ):date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'
クサラナンダ

:私は私のパターンにスラッシュ、ないパイプを持っている時はいつでもs|\.|/|g。それ以外の場合は、上記のとおり:ナイスキャッチ、+ 1
Alex Stragies 2017

2

他の回答で提示されたものとは異なる戦略:「。」を使用できます。フィールドセパレータとして。

awk -F. '$1 < 10 {printf "0"} {print}' /tmp/in.txt

あなたはこれをゴルフすることができます:

awk -F. '$1<10{printf "0"}1' /tmp/in.txt

sedの場合、別の(素晴らしい)回答で提示される短いコマンドがあります。


1
代替案: awk -F. '{print ($1<10?0$0:$0)}' file
George Vasiliou 2017

1

sedを使用すると

sed 's/^\(.\)\.\(.*\)/0\1.\2/'

これは^、行の先頭にアンカーするために使用し、グループ内の任意の1文字をキャプチャし.、その後にリテラルが続き、それから何でもキャプチャします。一致する場合、を印刷し0、次に最初のキャプチャグループ(行の先頭の文字)、次に.2番目のキャプチャグループ(行の残りの部分)


そのキャプチャを行う必要はまったくありません。&あなたの友だちです。Kusalanandaのsedの例を参照してください。
追って通知があるまで一時停止。

@DennisWilliamsonは必要ありませんが、すでに他の例があるため、これはsedこの特定の問題だけでなく、他の状況でも役立つ可能性のある別の機能を示しています
Eric Renouf
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.