我有一个字符串,我想在 awk 中对其进行子串(或剪切,或 sed,等等)。
但我想保留字段分隔符。
该文件在字段分隔符之后有完全随机数量的垃圾,其中包含随机数量的字符。
例如
狗.pgp.123sda
狗.pgpsjaksdasdasdaw
狗.pgp-asasdawad2
我希望所有三个输出都是:
狗.pgp
显然这里的公共字段是“.pgp”,但标准 awk 总是删除字段分隔符。
'{sub(/.pgp.*/,""); print}'
或者
awk -F".PGP." '{print $1}'
有没有办法维护分离器?
答案1
for string in Dogs.pgp.123sda Dogs.pgpsjaksdasdasdaw Dogs.pgp-asasdawad2
do
printf '%s --> %s\n' "$string" "${string%${string#*.???}}"
done
输出:
Dogs.pgp.123sda --> Dogs.pgp
Dogs.pgpsjaksdasdasdaw --> Dogs.pgp
Dogs.pgp-asasdawad2 --> Dogs.pgp
该循环迭代三个字符串。在循环体中,原始字符串与转换后的字符串一起打印。
通过删除字符串中第一个点之前的部分以及点之后的三个字符之外的所有内容来转换字符串。
这是通过首先弄清楚要从原始字符串中删除什么来完成的。这是${string#*.???}
,即删除第一个点和另外三个字符后的字符串的其余部分。然后通过 将该值从字符串的末尾删除${string%${string#*.???}}
。
如果循环迭代了文件名匹配 eg *.pgp*
,那么这也可以处理文件名包含换行符的情况。唯一会混淆上述转换的是.pgp
子字符串之前是否有点,但您可以通过.pgp
显式匹配而不是.???
:
for fname in *.pgp*
do
printf '%s --> %s\n' "$fname" "${fname%${fname#*.pgp}}"
done
答案2
怎么样:
awk -F '.pgp' '{print $1 FS}'
我很想使用perl -pe 's/\.pgp\K.*//'
awk 来代替。
答案3
我相信我使用匹配和子字符串解决了这个问题:
'match($0, /REGEX/) {sub(/REGEX/, substr($0, RSTART, RLENGTH) ); print}'
答案4
我尝试使用 awk substr 方法:
awk '{print substr($1,1,8)}' filename
输出是:
Dogs.pgp
Dogs.pgp
Dogs.pgp