使用Sed/Regex在bash中基于分隔符拆分行

使用Sed/Regex在bash中基于分隔符拆分行,regex,bash,sed,cut,Regex,Bash,Sed,Cut,雷格克斯新手,希望能改变这一点。我有以下看似非常简单的问题,我无法找到正确的正则表达式实现来正确解析。基本上,我有一个文件,其中的行如下所示: time:3:35PM 我只是想删掉所有字符,只包括第一个“:”分隔符,并用sed保持其余字符的完整性,这样我就可以处理许多格式相同的文件。我想得到的是: 3:35PM 下面是我得到的最接近的分隔符,但只是使用了最后一次出现的分隔符,而不是第一次出现的分隔符: sed 's/.*://' 我也尝试过python,但在应用python函数迭代多个文件

雷格克斯新手,希望能改变这一点。我有以下看似非常简单的问题,我无法找到正确的正则表达式实现来正确解析。基本上,我有一个文件,其中的行如下所示:

time:3:35PM
我只是想删掉所有字符,只包括第一个“:”分隔符,并用sed保持其余字符的完整性,这样我就可以处理许多格式相同的文件。我想得到的是:

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

sed 's/.*://'
我也尝试过python,但在应用python函数迭代多个文件中的所有行(而不是一个文件)时遇到了挑战


任何帮助都将不胜感激

删除每个实例,直到
,包括您可以执行的

sed -i.bak 's/^[^:]*://' file.txt
在多个
.txt
文件上

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

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

< P>由于不需要正则表达式匹配单个已知字符,请考虑使用而不是.< /P> 这个简单的表达式将
设置为
d
-elimiter并发出
f
-ields
2
,向前(
-
):

例如:

% echo 'time:3:35PM' | cut -d: -f2-
3:35PM

您几乎可以在每个文本处理工具中实现这一点(许多工具根本不使用正则表达式)

预计起飞时间 如果就地编辑非常重要,那么规范的正确方法不是sed(流编辑器),而是
ed
(文件编辑器)

ed“$file”“$file”。新建
mv“$file”。新建“$file”
猛击 这不会导致产生任何新进程。(不管值多少钱。)

而IFS=:读取时间;做
printf“%s\n”$time
完成<“$file”>“$file”。新建
mv“$file”。新建“$file”
awk
awk-F:'BEGIN{OFS=“:”}{print$2,$3}<“$file”>“$file”。新建
mv“$file”。新建“$file”
cut-d:-f2-<“$file”>“$file”。新建
mv“$file”。新建“$file”
有很多很好的替代方案,但您已经询问了如何使用
regex
实现这一点。以下是一些纯正则表达式解决方案:

grep -oP '[^:]*:\K.*' file.txt
\K
使它在发生
\K
之前忘记一切。 但如果您知道确切的前缀长度,则可以使用以下功能:


“代码> GRP- OP”(?< P>请考虑我的答案:

例如,您可以只写:

echo“时间:下午3:35”| cutr-d:-f2--r:
在您的特定情况下,您可以简单地使用
cut
,不过:

echo“时间:下午3:35”|切-d:-f2-

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

贪婪的匹配,嗯?
:)
试一试这个:
sed's/[^::::*://'
谢谢。我试过这样做,但我的理解是,不能使用剪切对多个文件进行就地编辑。@prometheus2305:没错,不进行就地编辑,但也不进行所有的实现。谢谢。我绝对专注于就地编辑。因此,如果我理解正确,我需要使用'ed'@prometheus2305:肯定会完成这项工作(如中所示)。使用你最舒服的工具。很好!甚至不知道“ed”。非常感谢。我可以问一下,如何在包含多个文件的多个目录中递归地应用ed选项吗?@prometheus2305如果您的shell可以递归地使用glob,那么您可以循环使用该glob表达式,如**/*中的f的
;这是相当全面的。我会先做
mv“${file}”“${file}.bak”
,然后使用
<“${file}.bak”>“${file}”
进行编辑,在发生事故时留下一个备份文件。
ed "$file" << EOF
,s/^[^:]*://g
w
EOF
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 -F: 'BEGIN{ OFS=":" } { print $2,$3 }' < "$file" > "$file".new
mv "$file".new "$file"
cut -d: -f2- < "$file" > "$file".new
mv "$file".new "$file"
grep -oP '[^:]*:\K.*' file.txt
grep -oP '(?<=^time:).*' file.txt