删除模式之前的所有内容

时间:2018-08-12 07:58:55

标签: bash perl awk sed

我正在尝试清除文本文件。

我想删除前12个数字之前的所有内容。

1:0:135103079189:0:0:2:0::135103079189:000011:00
A:908529896240:0:10250:2:0:1:
603307102606:0:0:1:0::01000::M

所需的输出:

135103079189:0:0:2:0::135103079189:000011:00
908529896240:0:10250:2:0:1:
603307102606:0:0:1:0::01000::M

这是我的命令,但似乎不起作用。

sed '/:\([0-9]\{12\}\)/d' t.txt

5 个答案:

答案 0 :(得分:2)

请您尝试以下。

awk --re-interval 'match($0,/[0-9]{12}/){print substr($0,RSTART)}' Input_file

由于我使用的是awk的旧版本,所以我正在使用--re-interval,如果您有新版本,可以将其删除。

答案 1 :(得分:2)

d中的sed命令将在匹配给定正则表达式时删除整行,您需要使用s命令来搜索和替换仅行的一部分...但是,对于给定问题,sed不适用,因为它不支持非贪婪的正则表达式

您可以改用perl

$ perl -pe's/^.*?(?=\d{12}:)//' ip.txt
135103079189:0:0:2:0::135103079189:000011:00
908529896240:0:10250:2:0:1:
603307102606:0:0:1:0::01000::M
  • .*?最少匹配零个或多个字符
    • (?=\d{12}:)仅在其后跟以:结尾的12位数字
  • 使用perl -i -pe进行就地编辑


一些可能的极端情况

$ # this is matching part of field
$ echo 'foo:123:abc135103079189:23:603307102606:1' | perl -pe's/^.*?(?=\d{12}:)//'
135103079189:23:603307102606:1
$ # this is not matching 12-digit field at end of line
$ echo 'foo:123:135103079189' | perl -pe's/^.*?(?=\d{12}:)//'
foo:123:135103079189

$ # so, add start/end of line matching cases and restrict 12-digits to whole field
$ echo 'foo:123:abc135103079189:23:603307102606:1' | perl -pe 's/^(?:.*?:)?(?=\d{12}(:|$))//'
603307102606:1
$ echo 'foo:123:135103079189' | perl -pe's/^(?:.*?:)?(?=\d{12}(:|$))//'
135103079189

答案 2 :(得分:1)

这可能对您有用(GNU sed):

sed -n 's/[0-9]\{12\}/\n&/;s/.*\n//p' file

我们只想打印特定的行,因此请使用-n选项关闭自动打印。如果一行包含12位数字,请在其前面插入换行符。删除换行符之前和包括的所有字符,然后打印结果。

如果要按原样打印不包含12位数字的行,请使用:

sed 's/[0-9]\{12\}/\n&/;s/.*\n//' file

问题的症结在于识别多字符字符串的开头,插入一个唯一标记并删除该唯一标记之前(包括该唯一标记)的所有字符。由于sed使用换行符来分隔行,因此只有用户可以将换行符引入模式空间,结果换行符将始终是唯一的。

答案 3 :(得分:0)

从@Sundeep处获得很好的答案,以防万一您想使用SELECT convert(datetime, '23-10-2016', 105) -- dd-mm-yyyy grep(macOS / BSD),可以尝试:

pcregrep

$ grep -oP '^(?:.*?:)?(?=\d{12})\K.*' file

$ pcregrep -o '^(?:.*?:)?(?=\d{12})\K.*' file 将忽略模式之后的所有内容

答案 4 :(得分:0)

另一种想法-我几乎认为您的数据太脏了,无法快速进行sed修复,但是如果通常它都与您的样本数据集相似,则可以肯定选择sed等答案之一。但是,如果您想更具体一点关于它,您可以建立一组命令来确保值。我喜欢这样做,以便进行调试以及速度不紧急的情况。

以这个很小的代码示例为例,您可以采用其他方法来执行此操作,但是我正在获取字符串每个部分的值,并且我知道顺序,因为它是连续的。然后,您可以设置要保留哪些部分的控件,例如要建立的控件,每行说一个新字符串。确实过度劳累,但有时这是一种更好的长期方法。

#!/bin/bash
while IFS= read -r line ;do
        IFS=':' read -r -a array <<< "$line"
        for ((i=0; i<${#array[@]}; i++)) ;do
                echo "part : ${array[$i]}"
        done
done < "test_data.txt"

然后,您可以根据需要备份数据,并更轻松地了解整个过程中发生的事情..

part : 1
part : 0
part : 135103079189
part : 0
part : 0
part : 2
part : 0
part :
part : 135103079189
part : 000011
part : 00
part : A
part : 908529896240
part : 0