จะลบโคลอนแรก ':' ออกจากเวลาได้อย่างไร


10

ฉันใหม่กับการเขียนโปรแกรม !!

ทุกคนสามารถช่วยในการลบ:ที่ตำแหน่งแรกในการประทับเวลา::29.06.2019 23:03:17

ปัจจุบันฉันพยายามทำโดยใช้คำสั่ง awk / cut ดังที่แสดงด้านล่าง:

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


29.06.2019 23

และผลลัพธ์ไม่ใช่สิ่งที่ฉันต้องการ! 29.06.2019 23:03:17ฉันต้องการพิมพ์เป็น

คำตอบ:


14

หากต้องการตัดอักขระแรกคุณสามารถใช้cut -c:

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

11

ใช้

cut -d: -f2-

แทน

cut -d: -f2

เพื่อรับอะไรจากฟิลด์ที่สองถึงจุดสิ้นสุดของบรรทัด:

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

8

awkเป็นเครื่องมือที่ยอดเยี่ยมและคุณสามารถแก้ปัญหาที่ซับซ้อนได้ แต่สำหรับคำถามของคุณฉันอยากจะใช้ความสามารถพื้นฐานของการทุบตี

สำหรับการลบ substing ง่าย ๆ นี้ฉันจะทำสิ่งต่อไปนี้:

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

สิ่งนี้จะพิมพ์:

29.06.2019 23:03:17

เมื่อฉันอยู่ในตำแหน่งของคุณและเริ่มเรียนรู้การเขียนโปรแกรมและการทุบตีฉันได้เรียนรู้คู่มือเล่มนี้มากมาย:

ABS - คู่มือ Bash-Scripting ขั้นสูง

ตัวอย่างเพิ่มเติมและข้อมูลที่น่าสนใจเกี่ยวกับปัญหาของคุณสามารถดูได้ที่นี่มองหา 'กำจัดซับสตริง'


3
+1 นี่! เนื่องจากคำถามถูกแท็ก "bash" ดังนั้นจึงควรพิจารณาความสามารถที่ยอดเยี่ยม (แต่มักจะค่อนข้างคลุมเครือ) ของการจัดการสตริงซึ่งเร็วกว่าการโหลดเครื่องมือภายนอก
rexkogitans

2
@rexkogitans เนื่องจากเรากำลังเรียก grep หรือ awk เพื่อแยกวิเคราะห์ไฟล์การทุบตีจะไม่เร็วขึ้น ในความเป็นจริงเมื่อใดก็ตามที่คุณต้องการแยกวิเคราะห์ไฟล์ bash จะช้า กระสุนทั้งหมดนั้นช้าและ bash นั้นช้ากว่ามาก ความสามารถในการจัดการสตริงของเชลล์มักจะเป็นวิธีที่ดีที่สุด แต่ถ้าคุณมีอินพุตเป็นตัวแปรอยู่แล้ว
terdon

8

นี่คือsedทางออก:

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

สิ่งที่คำสั่งsed 's/^://'จะทำคือใช้แทนsตัวอักษรลำไส้ใหญ่:จากจุดเริ่มต้นของแต่ละบรรทัดกับสตริงที่ว่างเปล่า^//

นี่คือawkทางออกที่ยุ่งยากซึ่งเราเปลี่ยนตัวคั่นฟิลด์เป็น^:อธิบายข้างต้นและส่งออกฟิลด์ที่สอง (ของแต่ละบรรทัด):

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

งานสามารถทำได้ด้วยgrep( คำอธิบาย ) อาจเป็นวิธีแก้ปัญหาที่เร็วที่สุดสำหรับข้อมูลจำนวนมาก:

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

หรือประมวลผลไฟล์โดยตรงโดยใช้คำสั่งต่อไปนี้โดยที่ข้อ จำกัด^ถูกลบออก:

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

ข้างต้นสามารถทำได้โดยการsedจับกลุ่ม()->\1:

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

ในกรณีที่การแสดงออกจะตรงกับสายทั้งที่มี^.*<something>.*$ <something>คำสั่งs/old/new/จะแทนที่บรรทัดนี้ด้วยเนื้อหาของกลุ่มการจับภาพแรก (การแสดงออกในวงเล็บอาจเป็นรูปธรรมมากขึ้น) ตัวเลือก-rเปิดใช้งานการแสดงออกปกติเพิ่มเติม ตัวเลือก-nจะระงับการส่งออกปกติsedและสุดท้ายคำสั่งpจะพิมพ์การแข่งขัน


ฉันไม่เคยรู้เลยว่าawkจะมีตัวละคร FS หลายตัวพร้อมตัวละครที่มีความหมายพิเศษ! สิ่งที่ฉันเรียนรู้วันนี้
Floris

6

เนื่องจากคุณกำลังประมวลผลอยู่ในนี้awkคุณอาจทำสิ่งทั้งหมดโดยตรง:

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

subรูปแบบทั่วไปคำสั่งเป็นsub(/REGEX/, REPLACEMENT, TARGET)และจะเข้ามาแทนที่การแข่งขันทั้งหมดสำหรับการแสดงออกปกติREGEXกับสตริงในสายป้อนREPLACEMENT TARGETที่นี่เรากำลังแทนที่อันแรก:( ^หมายถึง "จุดเริ่มต้น") จากฟิลด์ที่ 3 ( $3) โดยไม่มีอะไร

แน่นอนว่าถ้าคุณทำสิ่งนั้นใน awk คุณอาจทำทุกอย่างใน awk และทำทุกอย่างให้เสร็จในการใช้งานครั้งเดียว:

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

หรือในกรณีของคุณ:

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

0

โซลูชั่นทุบตีอื่น:

$ echo "Logfile started :29.06.2019 23:03:17" | xargs bash -c 'echo "${2#*:} $3"'
29.06.2019 23:03:17
  • สิ่งนี้ใช้ไพพ์ไลน์แทนการกำหนดตัวแปรกลาง
  • คำสั่งxargsแปลงstdin(อินพุตมาตรฐาน) เป็นพารามิเตอร์ตำแหน่งสำหรับbashคำสั่ง
  • แทนที่ด้วยechotail -n1 /path/to/reportfile.txt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.