[英]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.