正在处理的数据将遵循特定的模式。在这种情况下,我想隔离第三列中找到的所有字符,并返回在“-”但前提是该分隔符存在于列中。否则它不应该返回任何内容。
eval $A=$(echo $1 | awk -F"." '{print $3}' | cut -d\- -f2-)
第一条awk
语句将字符串分解为
111
222
333-ab3-On21-2
该cut
命令打印第一个“-”之后的字符。
字符串 1 111.2222.333-ab3-On21-2
返回期望的结果:
ab3-On21-2
字符串2 111.2222.334
返回不需要的结果:
333
字符串的最后一部分中不存在分隔符"-"
,在这种情况下如何更改此代码以返回 0 或“”?
答案1
我不确定你从哪里得到“条件”,因为你的陈述中没有任何条件。没有awk -F- {print}
做任何有用的事情;只是将输入传递到输出。
但是,您可以使用表达式执行您想要的操作sed
,以简化整个管道:
sed -n 's/.*\.[^-]*-\(.*\)/\1/p'
-n
和意味着p
它只会打印与表达式匹配的字符串。
该表达式将删除直到最后一个.
,然后删除第一个之前的所有内容-
。
所以:
% echo 111.2222.333-ab3-On21-2 | sed -n 's/.*\.[^-]*-\(.*\)/\1/p'
ab3-On21-2
% echo 111.2222.333 | sed -n 's/.*\.[^-]*-\(.*\)/\1/p'
%
如果您的输入更复杂(例如可能有四个.
分隔字段),那么模式可能需要更聪明一些。
sed -n 's/.*\.[^-]*-\([^\.]*\).*/\1/p'
例如
% echo 111.2222.333-ab3-On21-2.999 | sed -n 's/.*\.[^-]*-\([^\.]*\).*/\1/p'
ab3-On21-2
答案2
grep -o -P '[^.]*\.[^.]*\.[^-]*-\K.*'
起初我想到使用正向后查找,但它不适用于非固定长度的正则表达式。然后,我做了一些谷歌搜索,发现 Perl 有\K
重置匹配的令牌。
例子:
grep -o -P '[^.]*\.[^.]*\.[^-]*-\K.*' <<< 111.222.333-ab3-0n21-2
ab3-0n21-2
grep -o -P '[^.]*\.[^.]*\.[^-]*-\K.*' \
<<< '128-2sd83--.3 832 @!@!# 323.7 dskj ...-ab3-0n21-2'
ab3-0n21-2
答案3
cut
将, 与-s
(或) 选项一起使用--only-delimited
:
printf '%s\n' '111.2222.333-ab3-On21-2' '111.2222.334' |
cut -d '.' -f 3 | cut -d '-' -sf 2-
输出:
ab3-On21-2