我用简单的例子进行了测试,如下所示:
bash-3.2$ echo "1|2|3|4|5|6|7|8" | nawk -F\| '{print $(NF-4)}'
4
期待结果:
1|2|3|5|6|7|8
如何更改命令以获得所需的输出?
答案 0 :(得分:2)
如果我理解正确,你想使用这样的东西:
sed -E 's/\|[^|]*((\|[^|]*){4})$/\1/'
这匹配管道字符\|
后跟任意数量的非管道字符[^|]*
,然后再捕获4个相同模式((\|[^|]*){4})
。最后的$
与行尾相匹配。匹配的第一部分(即结尾的第五个字段)被删除。
测试出来:
$ sed -E 's/\|[^|]*((\|[^|]*){4})$/\1/' <<<"1|2|3|4|5|6|7"
1|2|4|5|6|7
你可以使用gensub
使用GNU awk来实现相同的功能,但我认为在这种情况下sed是正确的工具。
如果您的sed版本不支持使用-E
扩展的正则表达式语法,则可以稍微修改它:
sed 's/|[^|]*\(\(|[^|]*\)\{4\}\)$/\1/'
在基本模式下,管道按字面解释,但是对于捕获组而言是括号,而卷曲的是用于转义。
答案 1 :(得分:1)
AWK 是您的朋友:
示例输入
A|B|C|D|E|F|G|H|I
A|B|C|D|E|F|G|H|I|A
A|B|C|D|E|F|G|H|I|F|E|D|O|R|Q|U|I
A|B|C|D|E|F|G|H|I|E|O|Q
A|B|C|D|E|F|G|H|I|X
A|B|C|D|E|F|G|H|I|J|K|L
<强>脚本强>
awk 'BEGIN{FS="|";OFS="|"}
{$(NF-5)="";sub(/\|\|/,"|");print}' file
示例输出
A|B|C|E|F|G|H|I
A|B|C|D|F|G|H|I|A
A|B|C|D|E|F|G|H|I|F|E|O|R|Q|U|I
A|B|C|D|E|F|H|I|E|O|Q
A|B|C|D|F|G|H|I|X
A|B|C|D|E|F|H|I|J|K|L
我们在这里做了什么
$1
,$2
到$(NF)
$(NF-5)=""
|
即{h} sub(/\|\|/,"|")
答案 2 :(得分:1)
另一种选择,使用@ sjsam的输入文件
$ rev file | cut -d'|' --complement -f6 | rev
A|B|C|E|F|G|H|I
A|B|C|D|F|G|H|I|A
A|B|C|D|E|F|G|H|I|F|E|O|R|Q|U|I
A|B|C|D|E|F|H|I|E|O|Q
A|B|C|D|F|G|H|I|X
A|B|C|D|E|F|H|I|J|K|L
不确定你想要从最后一个或第六个开始的第5个。但它很容易调整。
答案 3 :(得分:0)
感谢您的帮助和指导。
以下是我测试的内容:
bash-3.2 $ echo&#34; 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9&#34; | nawk&#39; BEGIN {FS =&#34; |&#34 ;; OFS =&#34; |&#34;} {$(NF-4)=&#34;!&#34 ;;打印}&#39; | sed&#39; s / |!//&#39;
输出:1 | 2 | 3 | 4 | 6 | 7 | 8 | 9
对我从系统中提取的文件进行了进一步测试,因此工作正常。