İlk iki nokta üst üste ':' zaman damgasından nasıl kaldırılır?


10

Programlamaya yeniyim !!

Herkes :bir zaman damgası ilk pozisyonda kaldırmak için yardımcı olabilir ::29.06.2019 23:03:17

Şu anda aşağıda gösterildiği gibi awk / cut komutlarını kullanarak yapmaya çalışıyorum:

TDS="$(grep 'Logfile started' process.log |  awk '{print $3,$4}' | cut -d: -f2)"
echo "$TDS"


29.06.2019 23

Ve çıktı istediğim gibi değil! Olarak yazdırmak istiyorum 29.06.2019 23:03:17.

Yanıtlar:


14

İlk karakteri kesmek için şunları da kullanabilirsiniz cut -c:

$ echo ":29.06.2019 23:03:17" | cut -c 2-
29.06.2019 23:03:17

11

kullanım

cut -d: -f2-

onun yerine

cut -d: -f2

ikinci alandan satır sonuna kadar bir şey almak için:

TDS="$(grep 'Logfile started' process.log |  awk '{print $3,$4}' | cut -d: -f2-)"
echo "$TDS"

8

awkharika bir araçtır ve onunla çok karmaşık görevleri çözebilirsiniz. Ama sorunuz için bash'ın temel yeteneklerine bağlı kalmayı tercih ederim.

Bu kolay alt tabaka kaldırma için aşağıdakileri yaparım:

zehe="Logfile started :29.06.2019 23:03:17"
echo "${zehe#*:}"

bu yazdırılacaktır:

29.06.2019 23:03:17

Ben senin pozisyonundayken programlama ve bash öğrenmeye başladığımda, bu El Kitabından çok şey öğrendim:

ABS - Gelişmiş Bash-Scripting Kılavuzu

Sorununuzla ilgili daha fazla örnek ve ilginç bilgi burada bulunabilir , 'Alt Tabakanın Çıkarılması' konusuna bakın.


3
+1 Bunu! Soru "bash" olarak etiketlendiğinden, harici araçların yüklenmesinden çok daha hızlı olan dizeleri işlemek için bash'ın büyük (genellikle oldukça belirsiz) yeteneklerini tercih ettiği düşünülmelidir.
rexkogitans

2
@rexkogitans zaten bir dosyayı ayrıştırmak için grep veya awk çağırdığımız için bash daha hızlı olmayacak. Aslında, bir dosyayı ayrıştırmanız gerektiğinde bash yavaş olacaktır. Tüm mermiler yavaş ve bash çok daha yavaş. Bununla birlikte, kabuğun dize düzenleme yetenekleri gerçekten de en iyi yaklaşımdır, ancak yalnızca bir değişken olarak girdiniz varsa.
terdon

8

İşte bir sedçözüm:

$ echo ':29.06.2019 23:03:17' | sed 's/^://'
29.06.2019 23:03:17

Komutun sed 's/^://'yaptığı, her satırın başındaki siki nokta karakterini boş dize ile değiştirmek .:^//

awkAlan ayırıcısını ^:yukarıda açıklandığı gibi değiştirdiğimiz ve ikinci alanı (her satırın) çıktısını verdiğimiz zor bir çözüm :

$ echo ':29.06.2019 23:03:17' | awk -F'^:' '{print $2}'
29.06.2019 23:03:17

Görev de grep( açıklama ) ile gerçekleştirilebilir , muhtemelen bu büyük miktarda veri için en hızlı çözüm olabilir:

$ echo 'Logfile started :29.06.2019 23:03:17' | grep -Po '^Logfile started :\K.*'
29.06.2019 23:03:17

Veya dosyayı doğrudan sınırlamanın ^kaldırıldığı aşağıdaki komutla işleyin:

grep -Po 'Logfile started :\K.*' process.log

Yukarıdakiler aynı zamanda sedve yakalama grupları tarafından da gerçekleştirilebilir ()->\1:

sed -nr 's/^.*Logfile started :(.*)$/\1/p' process.log

İfadenin ^.*<something>.*$, tüm satırı eşleştireceği yer <something>. Komut s/old/new/, bu satırı ilk yakalama grubunun içeriğiyle değiştirir (parantez içindeki ifade daha somut olabilir). Bu seçenek -r, genişletilmiş düzenli ifadeleri etkinleştirir. Seçenek -nnormal çıktısını bastıracak sedve son olarak komut peşleşmeleri yazdıracaktır.


awkÖzel anlam taşıyan karakterlere sahip çok karakterli bir FS olabileceğini hiç bilmiyordum ! Bugün öğrendiğim bir şey.
Floris

6

Bunu zaten işlediğiniz awkiçin, her şeyi doğrudan da yapabilirsiniz:

$ echo "foo bar :29.06.2019 23:03:17" |  awk '{sub(/^:/,"",$3); print $3,$4}' 
29.06.2019 23:03:17

subKomutunun genel biçimidir sub(/REGEX/, REPLACEMENT, TARGET)ve düzenli ifadesi için tüm eşleşmeleri yerini alacak REGEXdize ile REPLACEMENTgiriş dizesi TARGET. Burada, birinci alanın ( ) ilkini :( ^"başlangıç" anlamına gelir $3) hiçbir şeyle değiştirmiyoruz.

Elbette, bunu awk ile yapıyorsanız, her şeyi awk ile de yapabilir ve her şeyi tek bir işlemle yapabilirsiniz:

$ echo "Logfile started :29.06.2019 23:03:17" | 
    awk '/Logfile started/{sub(/^:/,"",$3); print $3,$4}' 
29.06.2019 23:03:17

Veya, sizin durumunuzda:

TDS="$(awk '/Logfile started/{sub(/^:/,"",$3); print $3,$4}' process.log)"
echo "$TDS"

0

Başka bir bash çözümü:

$ echo "Logfile started :29.06.2019 23:03:17" | xargs bash -c 'echo "${2#*:} $3"'
29.06.2019 23:03:17
  • Bu, ara değişken ataması yerine ardışık düzen kullanır.
  • Komut xargs, stdin(standart girdi) bashkomut için konum parametrelerine dönüştürülür .
  • Değiştir echoile tail -n1 /path/to/reportfile.txt.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.