gpt4 book ai didi

bash - 删除 bash 中的反向匹配

转载 作者:行者123 更新时间:2023-12-02 09:04:08 25 4
gpt4 key购买 nike

我有一个文件 list.txt,其中包含:

234
243
324
342
423
432

如何查找是否存在反向模式(即 432 是 234 的反向模式)并删除反向模式?我已经尝试过了

while IFS= read -r line; do
reverse=$(echo $line|rev)
if grep -q $reverse list.txt; then
sed -i "s/$reverse//g" list.txt
else :
fi
done < list.txt

但这会删除 list.txt 中的每一行。我的预期输出是

234
243
324

我想要完成的事情可能吗?我的 MWE 是一个简短的列表,但这个列表可以(并且将会)大幅增长。提前致谢。

最佳答案

原始问题:删除输入中所有带有反转的项目

删除文件中与任何其他字符串相反的所有字符串将如下所示:

grep -Fvf <(rev list.txt) <list.txt >list.txt.new && mv list.txt.new list.txt

让我们分解一下:

  • grep -F仅匹配固定字符串。
  • grep -v 反转匹配,发出不匹配的内容。
  • grep -f filename读取要从 filename 中查找的模式列表
  • <(rev list.txt)process substitution扩展为一个文件名,其中 rev list.txt 的输出可以阅读。
  • <list.txt连接list.txt到您的 grep 的标准输入.
  • >list.txt.new将 grep 的 stdout 连接到新文件;这很重要,因为 >list.txt会在读取其原始内容之前覆盖您的输出文件。

但是,对于您的示例输入,这会导致完全空的输出 - 因为该示例输入文件中的每一行在该文件的其他位置都有一个相反的版本。


改进的问题:仅删除以前未见过的逆

鉴于您的示例数据,您确实不想删除输入文件中其他位置具有逆版本的所有数据。相反,您想要从上到下阅读,并仅打印其逆尚未见过的内容。

实现此目的的一种方法如下:

#!/usr/bin/env bash
case $BASH_VERSION in ''|[123].*) echo "ERROR: Bash 4.0+ needed" >&2; exit 1;; esac

declare -A blacklisted=( )
while IFS= read -r orig <&3 && IFS= read -r rev <&4; do
[[ ${blacklisted[$orig]} ]] && continue
blacklisted[$rev]=1
printf '%s\n' "$orig"
done 3< list.txt 4< <(rev list.txt) >list.txt.new && mv list.txt.new list.txt

顺便说一句,请注意,在现实世界中,不要硬编码类似 list.txt.new 的内容。 ,你应该使用mktemp为临时文件创建一个保证唯一/随机的名称。这不仅解决了并发问题,还解决了 security bugs .

关于bash - 删除 bash 中的反向匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60441063/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com