Làm cách nào để xóa dấu hai chấm đầu tiên ':' khỏi dấu thời gian?


10

Tôi mới lập trình !!

Bất cứ ai có thể giúp loại bỏ :vị trí đầu tiên trong dấu thời gian::29.06.2019 23:03:17

Hiện tại tôi đang cố gắng thực hiện bằng các lệnh awk / cut như hình dưới đây:

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


29.06.2019 23

Và đầu ra không phải là những gì tôi muốn! Tôi muốn in nó như 29.06.2019 23:03:17.

Câu trả lời:


14

Để cắt bỏ ký tự đầu tiên, bạn cũng có thể sử dụng cut -c:

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

11

Sử dụng

cut -d: -f2-

thay vì

cut -d: -f2

để lấy bất cứ thứ gì từ trường thứ hai đến cuối dòng:

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

8

awklà một công cụ tuyệt vời và bạn có thể giải quyết các nhiệm vụ rất phức tạp với nó. Nhưng đối với câu hỏi của bạn, tôi thích bám vào các khả năng cơ bản của bash.

Để loại bỏ trạm biến áp dễ dàng này, tôi sẽ làm như sau:

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

cái này sẽ in:

29.06.2019 23:03:17

Khi tôi ở vị trí của bạn và bắt đầu học lập trình và bash, tôi đã học được rất nhiều Sổ tay này:

ABS - Hướng dẫn Bash-Scripting nâng cao

Một số ví dụ và thông tin thú vị cho vấn đề của bạn có thể được tìm thấy ở đây , hãy tìm 'Loại bỏ chuỗi con'.


3
+1 này! Vì câu hỏi được gắn thẻ "bash", nên nó được coi là ưu tiên các khả năng tuyệt vời (mặc dù thường khá khó hiểu) của bash, nhanh hơn nhiều so với tải các công cụ bên ngoài.
rexkogitans

2
@rexkogitans vì chúng tôi đã gọi grep hoặc awk để phân tích tệp, bash sẽ không nhanh hơn. Trong thực tế, bất cứ khi nào bạn cần phân tích cú pháp bash sẽ bị chậm. Tất cả các shell đều chậm và bash chậm hơn hầu hết. Điều đó nói rằng, khả năng thao tác chuỗi của shell thực sự thường là cách tiếp cận tốt nhất, nhưng chỉ khi bạn đã có đầu vào dưới dạng một biến.
terdon

8

Đây là một sedgiải pháp:

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

Những gì lệnh sed 's/^://'đang làm là thay thế ský tự dấu hai chấm :từ đầu ^mỗi dòng bằng chuỗi trống //.

Đây là một awkgiải pháp khó , trong đó chúng tôi thay đổi dấu tách trường thành ^:, được mô tả ở trên và xuất trường thứ hai (của mỗi dòng):

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

Nhiệm vụ có thể được hoàn thành cũng với grep( giải thích ), có lẽ đây có thể là giải pháp nhanh nhất cho lượng dữ liệu lớn:

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

Hoặc xử lý tệp trực tiếp bằng lệnh sau, trong đó giới hạn ^được loại bỏ:

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

Những điều trên cũng có thể đạt được bởi sedvà nắm bắt các nhóm ()->\1:

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

Trường hợp biểu thức ^.*<something>.*$sẽ khớp với toàn bộ dòng, có chứa <something>. Lệnh s/old/new/sẽ thay thế dòng này bằng nội dung của nhóm chụp đầu tiên (biểu thức trong ngoặc có thể cụ thể hơn). Tùy chọn -rcho phép các biểu thức chính quy mở rộng. Tùy chọn -nsẽ triệt tiêu đầu ra bình thường sedvà cuối cùng lệnh psẽ in các trận đấu.


Tôi không bao giờ biết awkcó thể có một nhân vật đa nhân vật với các nhân vật có ý nghĩa đặc biệt! Điều tôi đã học ngày hôm nay.
Floris

6

Vì bạn đã xử lý việc này rồi awk, bạn cũng có thể trực tiếp thực hiện toàn bộ việc này:

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

Các subđịnh dạng chung của lệnh là sub(/REGEX/, REPLACEMENT, TARGET)và sẽ thay thế tất cả các trận đấu cho các biểu thức chính quy REGEXvới chuỗi REPLACEMENTtrong chuỗi đầu vào TARGET. Ở đây, chúng tôi đang thay thế cái đầu tiên :( ^có nghĩa là "sự khởi đầu") từ trường thứ 3 ( $3) bằng không có gì.

Tất nhiên, nếu bạn đang làm điều đó trong awk, bạn cũng có thể làm mọi thứ trong awk và hoàn thành mọi việc trong một thao tác duy nhất:

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

Hoặc, trong trường hợp của bạn:

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

0

Một giải pháp bash khác:

$ echo "Logfile started :29.06.2019 23:03:17" | xargs bash -c 'echo "${2#*:} $3"'
29.06.2019 23:03:17
  • Điều này sử dụng các đường ống thay vì gán biến trung gian.
  • Lệnh xargschuyển đổi stdin(đầu vào tiêu chuẩn) thành các tham số vị trí cho bashlệnh.
  • Thay thế echobằng tail -n1 /path/to/reportfile.txt.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.