Kami dapat menggunakan salah satu sed
atau awk
untuk sepenuhnya menyelesaikan masalah.
Dengan sed
:
$ sed 's/^.\./0&/' file.txt
Ketika &
terjadi di bagian penggantian dari perintah substitusi ( s
), itu akan diperluas ke bagian dari garis input yang cocok dengan bagian pola dari perintah.
Ekspresi reguler ^.\.
berarti " cocok dengan semua baris yang dimulai dengan ( ^
) karakter arbitrer ( .
) diikuti oleh titik literal ( \.
) ".
Jika garisnya 1.02.2017 23:40:00
, polanya akan cocok, dan 1.
akan diganti dengan 01.
di awal garis.
Dengan awk
:
Membangun awk
kode parsial dalam pertanyaan ...
Ini akan, seperti yang dinyatakan, mencetak karakter kedua dari setiap baris input:
$ awk '{ print substr($0, 2, 1) }' file.txt
Kita dapat menggunakan fakta yang substr($0, 2, 1)
mengembalikan karakter kedua dan menggunakannya sebagai syarat:
$ awk 'substr($0, 2, 1) == "." { ... }' file.txt
Apa yang masuk ke dalam { ... }
adalah kode yang diawali $0
, yang merupakan isi dari baris saat ini, dengan nol jika kondisi sebelumnya benar:
$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 }' file.txt
Maka kita hanya perlu memastikan bahwa semua garis dicetak:
$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 } { print }' file.txt
Kondisi substr($0, 2, 1) == "."
tentu saja dapat diubah menjadi ekspresi reguler juga (kami menggunakan ekspresi yang sama persis seperti yang kami gunakan dalam sed
solusi):
$ awk '/^.\./ { $0 = "0" $0 } { print }' file.txt
Beberapa orang yang berpikir "lebih pendek selalu lebih baik" akan menuliskannya sebagai
$ awk '/^.\./ { $0 = "0" $0 } 1' file.txt
(dan mungkin juga menghapus sebagian spasi: awk '/^.\./{$0="0"$0}1' file.txt
)
sed 's/^.\./0&/' file.txt
,. Saya pikir Anda harus meletakkan itu di awal jawaban ini. Tetap, +1.Dengan sed:
Pola
/^.\./
mencari karakter dan titik literal di awal baris^
, dan jika cocok,s
ubstitute yang memulai baris dengan nol, secara efektif menambahkan nol ke awal.Sed expressoin
s/.\{0\}/0/
agak aneh, cocok dengan nol atau lebih salinan apa pun dan diganti dengan nol. Pola ini tentu saja akan cocok di setiap posisi string, tetapi karenas///
hanya menggantikan pertandingan pertama, itu berfungsi seperti yang Anda inginkan. Namun, cara yang aneh untuk melakukannya.Atau dengan awk, regex yang sama akan bekerja untuk mencocokkan garis, tetapi kita dapat menggunakan
substr
:Kami pertama-tama menguji apakah karakter kedua adalah sebuah titik, kemudian tambahkan nol ke depan garis jika demikian. Yang terakhir memanggil tindakan standar mencetak garis setelah modifikasi.
sumber
Anda mengatakan awk dan sed, tetapi sepertinya Anda mencoba untuk memformat tanggal dan untuk itu saya akan menggunakan
date
perintah. Contohnya:akan menampilkan
The
sed
perintah di tengah perubahan periode ke garis miring untuk masukan kedate -d
. Opsi format memungkinkan output di hampir semua format yang Anda inginkan. Secara%m
khusus akan nol pad bulan, yang sepertinya Anda coba lakukan.Seperti yang ditunjukkan Kusalananda:
Bahkan lebih ringkas (tanggal GNU dan Bash):
date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'
sumber
date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'
s|\.|/|g
. Kalau tidak, seperti disebutkan di atas: Tangkapan bagus, +1Strategi yang berbeda dari yang disajikan dalam jawaban lain: Anda bisa menggunakan "." sebagai pemisah bidang.
Anda bisa bermain golf ini ke:
Untuk sed, ada perintah yang lebih pendek, disajikan dalam jawaban (bagus) lainnya.
sumber
awk -F. '{print ($1<10?0$0:$0)}' file
Dengan sed bisa jadi
Ini akan digunakan
^
untuk berlabuh ke awal baris, kemudian menangkap karakter tunggal dalam grup, diikuti oleh literal.
, lalu hal lainnya. Jika kami cocok dengan yang kami cetak0
, maka grup tangkapan pertama kami (karakter di awal baris), lalu.
grup tangkapan kedua kami (sisa baris)sumber
&
adalah temanmu Lihat contoh sed Kusalananda.sed
yang dapat berguna dalam situasi lain, bukan hanya masalah khusus ini