3

正则表达式新秀并希望改变这一点。我有以下看似非常简单的问题,我无法正确解析正确的正则表达式实现。基本上我有一个文件,其中包含如下所示的行:

time:3:35PM

我只是想删除所有字符,包括仅第一个':'分隔符,并使用 sed 保持其余字符完整,以便我可以处理许多具有相同格式的文件。我想要得到的是:

3:35PM

下面是我得到的最接近的,但只是使用最后一次出现的分隔符而不是第一次出现。:

sed 's/.*://'

我也尝试过使用 python,但是在应用 python 函数来遍历许多文件中的所有行而不是一个文件时遇到了挑战。

任何帮助将不胜感激。

4

5 回答 5

4

您可以在几乎所有文本处理工具中执行此操作(许多根本不使用正则表达式)。

如果就地编辑真的很重要,那么规范的正确方法不是 sed (编辑器)而是ed文件编辑器)。

ed "$file" << EOF
,s/^[^:]*://g
w
EOF

sed

(与 ed 几乎相同的命令,格式略有不同)

sed 's/^[^:]*://' < "$file" > "$file".new
mv "$file".new "$file"

重击

这不会导致产生任何新进程。(不管它值多少钱。)

while IFS=: read _ time; do
    printf '%s\n' "$time"
done < "$file" > "$file".new
mv "$file".new "$file"

awk

awk -F: 'BEGIN{ OFS=":" } { print $2,$3 }' < "$file" > "$file".new
mv "$file".new "$file"

cut -d: -f2- < "$file" > "$file".new
mv "$file".new "$file"
于 2013-09-14T21:49:53.447 回答
3

由于您不需要正则表达式来匹配单个已知字符,因此请考虑使用而不是

这个简单的表达式设置:d-elimiter 并发出f-ields 2,向前 ( -):

cut -d: -f2-

例子:

% echo 'time:3:35PM' | cut -d: -f2-
3:35PM
于 2013-09-14T21:35:36.293 回答
2

kojiro 的答案有很多很好的选择,但是您已经问过如何使用regex. 以下是一些纯正则表达式解决方案:

grep -oP '[^:]*:\K.*' file.txt

\K让它忘记发生之前的一切\K。但是,如果您知道确切的前缀长度,那么您可以使用环视功能:

grep -oP '(?<=^time:).*' file.txt

请注意,大多数正则表达式实现不支持这些功能。您可以将其grep-P标志及其perl本身一起使用。我想知道是否有任何其他实用程序支持这些。

于 2013-09-14T23:49:06.073 回答
1

要删除每个实例:,包括:你可以做的..

sed -i.bak 's/^[^:]*://' file.txt

在多个.txt文件上

sed -i.bak 's/^[^:]*://' *.txt

-i选项指定要就地编辑文件。通过创建一个临时文件并将输出发送到该文件而不是标准输出。

于 2013-09-14T21:28:24.970 回答
0

请在这里考虑我的回答:

如何在命令行中使用带有 cut 的正则表达式?

例如,您可以只写:

echo 'time:3:35PM' | cutr -d : -f 2- -r :

在您的特定情况下,您可以简单地使用cut

echo 'time:3:35PM' | cut -d : -f 2-

欢迎任何反馈。cutr还不完美,但在我投入太多时间之前,我想得到一些反馈。

于 2020-01-21T03:42:02.600 回答