Với GNU awk
:
$ printf '%s\n' {foo,bar}{bar,foo} neither | gawk 'xor(/foo/,/bar/)'
foofoo
barbar
Hoặc di chuyển:
awk '((/foo/) + (/bar/)) % 2'
Với sự grep
hỗ trợ cho -P
(PCRE):
grep -P '^((?=.*foo)(?!.*bar)|(?=.*bar)(?!.*foo))'
Với sed
:
sed '
/foo/{
/bar/d
b
}
/bar/!d'
Nếu bạn muốn xem xét toàn bộ chỉ từ (rằng có không phải là foo
hay bar
trong foobar
hoặc barbar
chẳng hạn), bạn sẽ cần phải quyết định như thế nào những từ được phân cách. Nếu đó là bởi bất kỳ ký tự nào ngoài các chữ cái, chữ số và dấu gạch dưới như -w
tùy chọn của nhiều cách grep
thực hiện, thì bạn sẽ thay đổi chúng thành:
gawk 'xor(/\<foo\>/,/\<bar\>/)'
awk '((/(^|[^[:alnum:]_)foo([^[:alnum:]_]|$)/) + \
(/(^|[^[:alnum:]_)bar([^[:alnum:]_]|$)/)) % 2'
grep -P '^((?=.*\bfoo\b)(?!.*\bbar\b)|(?=.*\bbar\b)(?!.*\bfoo\b))'
Vì sed
điều đó trở nên hơi phức tạp trừ khi bạn có một sed
triển khai như GNU sed
hỗ trợ \<
/ \>
như các ranh giới từ như GNU awk
.