我正在尝试清除文本文件。
我想删除前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
答案 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