删除bash中的反向匹配

删除bash中的反向匹配,bash,awk,Bash,Awk,我有一个文件,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.tx

我有一个文件,
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
我想完成的事情可能吗?我的MWE是一个简短的列表,但是这个列表可以(并且将)显著增长。提前感谢。

原始问题:删除输入中所有带反转的项目 删除文件中与任何其他字符串相反的所有字符串如下所示:

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

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

这里有一个
awk
解决方案:

awk 'BEGIN{FS=""} !seen[$0]{s=""; for (i=NF; i>0; i--) s=s $i; seen[s]++; print}' file

说明:

  • 开始{FS=”“}
    :将输入文件分隔符设置为空字符串,以便输入中的每个字符都成为awk中的字段
  • !SEED[$0]{
    :如果SEED数组中未找到当前行
    • s=”“;
      :将
      s
      初始化为空字符串
    • for(i=NF;i>0;i--)s=s$i
      :运行反向循环并在
      s
    • seed[s]++;
      :将
      s
      存储在数组
      seed
    • 打印
      :打印当前行

你一次一个地做这件事有什么原因吗?一次处理整个列表会更有效率。@CharlesDuffy我想这正是我所想的/我所熟悉的。我仍在努力学习BASH。如何一次处理整个列表?或者
awk'FNR==NR{pats[$0]=1;next}!(pats中的$0)“您如何期望输出中包含
234
?您的文件包含
432
,而
234
是其反向,因此删除它显然是正确的。请记住,
是的,我想保留其反向未被看到的数据。您介意解释更多while循环步骤吗?我有一个下面有点麻烦…是读取list.txt和rev list.txt,然后…?@RobS,循环从
list.txt
读取一行(我们在文件描述符3上打开该行,因此使用
@RobS进行读取),顺便说一句,它不仅仅是“未被看到”这是一个重要的区别,但文件中的这一点没有看到;也就是说,重要的区别(在您将示例输出放在问题中之前不清楚)是逻辑需要关心排序,而只考虑文件中特定点之前存在的其他行,而不是考虑文件中任何地方的其他行。我很欣赏解释和输入,它确实帮助了像我这样的新手。
#!/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
awk 'BEGIN{FS=""} !seen[$0]{s=""; for (i=NF; i>0; i--) s=s $i; seen[s]++; print}' file
234
243
324