[英]How to print one line after the matching pattern using awk sed or cut command
我想打印文本文件的內容,直到模式匹配一個字符。 我使用awk
命令,但未能獲得所需的 output。
文件:
>cat abc1.txt
2020-05-02 07:48:44+0000
我試過的:
>cat abc1.txt | awk '{print $1}'
2020-05-02
所需的 output:
2020-05-02 07:48
請幫我。
$ echo '2020-05-02 07:48:44+0000' | awk -F: -v OFS=: '{print $1, $2}'
2020-05-02 07:48
$ echo '2020-05-02 07:48:44+0000' | cut -d: -f1-2
2020-05-02 07:48
您可以將默認字段分隔符更改為:
字符並打印前兩個字段
第一個解決方案:您能否嘗試以下操作。
awk 'match($0,/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}/){print substr($0,RSTART,RLENGTH)}' Input_file
第二種解決方案:使用rev
+ awk
使我們的替換更容易。
rev Input_file | awk '{sub(/[^:]*:/,"")} 1' | rev
第三種解決方案:使用sed
的臨時緩沖能力。
sed -E 's/([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}).*/\1/' Input_file
第四種解決方案:如果您的 Input_file 始終具有相同的輸入格式並且您不需要驗證日期的語法,請嘗試。
awk 'match($0,/^.*:/){print substr($0,RSTART,RLENGTH-1)}' Input_file
第 5 種解決方案:僅添加替代操作 awk 解決方案。
awk '{sub(/:[0-9]{2}\+.*/,"")} 1' Input_file
第 6 種解決方案:設置字段分隔符值並僅打印需要的字段。
awk -F' |:' '{print $1,$2":"$3}' Input_file
使用輸入和 output 字段分隔符 ( :
) 並使用 GNU awk 刪除最后一列:
awk 'BEGIN{FS=OFS=":"} {NF--; print}' abc1.txt
或更短:
awk 'BEGIN{FS=OFS=":"} {NF--}1' abc1.txt
Output:
2020-05-02 07:48
假設您已經對問題的性質給出了公平的表示,則不需要awk
、 sed
或cut
。 以下是僅使用bash
內置插件處理文本的四種方法:
bash
正則表達式[[ $(<./abc1.txt) =~ (^.+): ]] && printf %s "${BASH_REMATCH[1]}"
$(<./abc1.txt)
:讀取文件abc1.txt
的內容,根據bash
自己的man
頁比cat
更有效
=~
: 正則表達式運算符
(^.+):
: 捕獲從行首到最后一個冒號之前的每個字符
${BASH_REMATCH[1]}
:存儲正則表達式匹配的子串列表; 第一個捕獲組(在模式的括號內)存儲在索引 1
bash
參數代換: "$(<./abc1.txt)"
printf %s "${_%:*}"
${_%:*}
:下划線引用上一條命令的參數,即文件內容; 並且替換會刪除從最后一個冒號到字符串末尾的所有內容date
由於很清楚您正在使用日期,並且以明確定義的格式 (ISO-8601) 表示,因此date
命令可以執行旨在執行的操作:
# -j flag available on macOS:
date -jf '%F %T%z' "$(<./abc1.txt)" +'%F %R'
# -d option on other systems:
# [credit: @WalterA (see comments below)]
date -d "$(<./abc1.txt)" +"%F %R"
這使用輸入格式字符串"%F %T%z"
解析日期,該字符串描述了日期字符串的每個組成部分所代表的內容(參見Linux 程序員手冊 - STRFTIME(3)
),並重新格式化使用 output 字符串"%F %R"
,在這種情況下,它表示與原始日期字符串類似但沒有時區和秒數的日期字符串。
printf
printf
用於格式化文本。 所以這里它只是格式化文本以顯示前 16 個字符(它實際上將第一個字段的列寬限制為 16 個字符的寬度,但那是廢話):
printf '%16.16s\n' "$(<./abc1.txt)"
與 (4) 類似,但使用參數替換:
: "$(<./abc1.txt)"
printf "${_:0:16}"
除了(3)
¹ 沒有調用外部程序或命令,這提供了更多的可移植性、更高的可靠性/健壯性、更有效的執行(一般來說,除非您正在處理數百或更多的日期或文件,否則這將無法衡量),以及更少的系統資源。
awk
和sed
是強大的大炮,而不是特別輕量級的工具(它們都是成熟的、圖靈完備的腳本語言)。 不要僅僅因為其他人都這樣做,或者因為它是你所知道的:了解 bash 作為bash
可以做什么,你會從中受益匪淺。
¹
Yon 可以在 awk 中使用sub
function 刪除最后一次出現后的所有內容:
awk '{sub(/:[^:]*$/, "")} 1' abc1.txt
2020-05-02 07:48
我想打印文本文件的內容,直到模式匹配一個字符。
與您要保留的內容匹配的正則表達式:
[^:]*:[^:]*
兩個等效的 sed 命令僅保留與之匹配的內容:
sed 's|\([^:]*:[^:]*\).*|\1|'
sed -E 's|([^:]*:[^:]*).*|\1|'
樣品 output:
$ echo '2020 07:48:40:40+0000'|sed 's|\([^:]*:[^:]*\).*|\1|'
2020 07:48
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.