我有一个非常大的文件。我需要屏蔽特定位置和特定记录类型中的所有字符。我搜遍了所有地方,但找不到这个非常简单的任务的解决方案。这是一个例子
文件名:hello.txt
文件:
0120140206INPUT FILE
1032682842 MR SIMPSON
20231458 742 Evergreen Terrace
3034560817 GREEN
1032682842 MR GRIFFIN
20231458 Spooner Street
3034560817 RED
3001
我想做的是屏蔽以“10”开头的所有行的12-16位。像这样:
0120140206INPUT FILE
1032682842 XXXXXMPSON
20231458 742 Evergreen Terrace
3034560817 GREEN
1032682842 XXXXXIFFIN
20231458 Spooner Street
3034560817 RED
3001
答案 0 :(得分:4)
使用sed
sed -r '/^10/ s/^(.{11}).{5}/\1XXXXX/' file
0120140206INPUT FILE
1032682842 XXXXXMPSON
20231458 742 Evergreen Terrace
3034560817 GREEN
1032682842 XXXXXIFFIN
20231458 Spooner Street
3034560817 RED
3001
-r
sed中的有用选项--regexp-extended /^10/
搜索以10开头的行。s/^(.{11}).{5}/\1XXXXX/
掩码位置12-16到XXXXX 同样的想法,如果你的awk是gawk,并支持gensub()
函数:
awk '{$0=gensub(/^(10.{9}).{5}/,"\\1XXXXX",$0)}1' file
更新:@tripleee提供更短的一个:
sed -r 's/^(10.{9}).{5}/\1XXXXX/' file
答案 1 :(得分:2)
这可以是一种方式:
$ awk 'BEGIN{FS=OFS=""} $1$2=="10" {for(i=12;i<=16;i++) $i="X"}1' file
0120140206INPUT FILE
1032682842 XXXXXMPSON
20231458 742 Evergreen Terrace
3034560817 GREEN
1032682842 XXXXXIFFIN
20231458 Spooner Street
3034560817 RED
3001
BEGIN{FS=OFS=""}
将字段分隔符设置为“”,这样第一个字符将是第一个字段,第二个字符将是第二个字段... $1$2=="10" {for(i=12;i<=16;i++) $i="X"}
如果第一个字符为1
,第二个字符为0
,则从第12个字符更改为第16个字符为X
。1
true condition,被评估为默认的awk行为:{print $0}
。答案 2 :(得分:1)
这个awk可以工作:
awk '/^10/{q=substr($0, 12, 4); gsub(/./, "*", q); $0=substr($0, 1, 11) q substr($0, 17)}1' file
答案 3 :(得分:0)
这应该做:
awk '/^10/{q=substr($0,1,11);r=substr($0,17); $0=q "XXXXX" r }1' file
0120140206INPUT FILE
1032682842 XXXXXMPSON
20231458 742 Evergreen Terrace
3034560817 GREEN
1032682842 XXXXXIFFIN
20231458 Spooner Street
3034560817 RED
3001
答案 4 :(得分:0)
这可能适合你(GNU sed):
sed -r '/^10/{s/^(.{0,11})(.{0,5})/\1\n\2\n/;h;s/[^\n]/X/g;G;s/.*\n(.*)\n.*\n(.*)\n.*\n/\2\1/}' file
对于以10
开头的行:在预期蒙版的两侧放置两个标记,复制,用掩码字符替换标记以外的所有字符,附加副本并操纵标记之间的文本以定位掩模。
N.B。这适合短线,不会引入人工制品。
答案 5 :(得分:0)
您可以使用gawk固定宽度数据读取功能:
gawk -v FIELDWIDTHS="11 5 9999" -v OFS="" '/^10/ { $2 = "XXXXX" } ; { print }' file
请参阅https://www.gnu.org/software/gawk/manual/gawk.html#Constant-Size。
答案 6 :(得分:0)
您可以使用BASH:
while read f1 f2; do
if [[ $f1 =~ ^10 ]]; then
f2="XXXXX${f2:5}"
fi
echo $f1 $f2
done < hello.txt
如果你只需要用XXXXX
替换第二个字段的前5个字符,这将有效。
如果你需要用XXXXX
替换第12个到第16个字符而不考虑字段,你可以做更长的时间:
while read l; do
if [[ $l =~ ^10 ]]; then
b=${l:11}
e=${l:16}
t=${b/$e/}
l=${l/$t/XXXXX}
fi
echo $l
done < hello.txt
答案 7 :(得分:0)
perl替代
perl -p -i -e 's/^(10\d* )[A-Z ]{6}(.*)/$1XXXXXX$2/g' filename.txt