awk sed if语句


9

如果有“。”,我尝试将0开头。在该行的第二个字符处。我无法将两者结合起来。

awk '{ print substr( $0, 2, 1 ) }' file.txt 

显示第二个字符

sed -ie "s/.\{0\}/0/" file.txt

在开头添加零。

应该有一个“如果第二个字符是一个点”。

样本文件:

1.02.2017 23:40:00
10.02.2017 23:40:00

最后:

01.02.2017 23:40:00
10.02.2017 23:40:00

Answers:


12

我们可以使用sedawk完全解决问题。


sed

$ sed 's/^.\./0&/' file.txt

&替换命令(s)的替换部分出现时,它将被扩展到与命令的模式部分匹配的输入行部分。

正则表达式的^.\.意思是“ 匹配以(^)开头的所有行,任意字符(.)和文字点(\. ”。

如果行是1.02.2017 23:40:00,则模式将匹配,并在行的开头1.被替换01.


awk

awk以问题中的部分代码为基础...

如前所述,这将打印输入的每一行的第二个字符:

$ awk '{ print substr($0, 2, 1) }' file.txt

我们可以使用substr($0, 2, 1)返回第二个字符的事实并将其用作条件:

$ awk 'substr($0, 2, 1) == "." { ... }' file.txt

所涉及的是{ ... }prepens的代码$0,即当前行的内容,如果上述条件为true,则为零:

$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 }' file.txt

然后,我们只需要确保所有行都已打印:

$ awk 'substr($0, 2, 1) == "." { $0 = "0" $0 } { print }' file.txt

条件substr($0, 2, 1) == "."当然也可以更改为正则表达式(我们使用与sed解决方案中使用的表达式完全相同的表达式):

$ awk '/^.\./ { $0 = "0" $0 } { print }' file.txt

一些认为“越短越好”的人会这样写道:

$ awk '/^.\./ { $0 = "0" $0 } 1' file.txt

(大概也去除大部分的空间:awk '/^.\./{$0="0"$0}1' file.txt


1
+1您的上一个AWK示例或sed示例是执行此操作的正确方法。请注意,为清楚起见,它只能是一个。
暂停,直到另行通知。

以我的观点,“正确”的方法(不会摆弄空格,而且重量更轻)是您的最终版本sed 's/^.\./0&/' file.txt。我认为您应该将其放在答案的开头。不过,+ 1。
通配符

1
@Wildcard我们旨在取悦。
Kusalananda

5

与sed:

sed -e "/^.\./s/^/0/" file.txt 

模式/^.\./将在行的开头查找任何字符和文字点^,如果匹配,s则用零代替该行的开头,从而有效地将零添加到开头。

sed expressoin s/.\{0\}/0/有点奇怪,它匹配零个或多个副本,并替换为零。该模式当然会在字符串的每个位置都匹配,但是由于s///仅替换了第一个匹配项,因此它可以按预期工作。不过,这是一种古朴的方法。


或者使用awk,类似的正则表达式可以匹配该行,但是我们可以使用substr

awk 'substr($0, 2, 1) == "." {$0 = "0" $0} 1' file.txt 

我们首先测试第二个字符是否为点,然后将零添加到该行的开头。最后一个调用任何修改后的默认行为,即打印该行。


4

您说了awk和sed,但似乎您正在尝试格式化日期,为此,我将使用date命令。例如:

echo '1.2.2017 23:40:00' | sed 's/\./\//g' | xargs -0 date '+%m.%d.%Y %T' -d

将输出

01.02.2017 23:40:00

sed中间的命令将句号更改为斜线,以输入到中date -d。格式选项允许输出几乎所需的任何格式。该%m特别意志零垫的一个月,这是它好像你正在尝试做的。

正如Kusalananda指出的那样:

更紧凑(GNU日期和Bash): date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'


2
好赶上!更紧凑的date -f <(tr '.' '/' <dates.in) '+%m.%d.%Y %T'
格式

每当我的样式中有斜线但没有管道时:s|\.|/|g。否则,如上所述:不错,+ 1
Alex Stragies

2

与其他答案不同的策略是:您可以使用“。” 作为字段分隔符。

awk -F. '$1 < 10 {printf "0"} {print}' /tmp/in.txt

您可以打高尔夫球到:

awk -F. '$1<10{printf "0"}1' /tmp/in.txt

对于sed,有一个较短的命令,在另一个(最佳)答案中显示。


1
另类: awk -F. '{print ($1<10?0$0:$0)}' file
乔治·瓦西里乌

1

使用sed可能是

sed 's/^\(.\)\.\(.*\)/0\1.\2/'

这将用于^锚定到行的开头,然后捕获组中的任何单个字符,然后捕获文字,然后捕获其他任何字符.。如果匹配,则打印0,然后是第一个捕获组(行首的字符),然后是.第二个捕获组(行的其余部分)


根本不需要进行任何捕获。&是你的朋友。参见Kusalananda的sed示例。
暂停,直到另行通知。

@DennisWilliamson并不是必须的,但是鉴于已经有其他示例,这表明该功能的另一个功能sed可能在其他情况下有用,而不仅仅是这个特定问题
Eric Renouf
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.