列出作为列表中其他字符串的子字符串的字符串

Que*_*low 7 bash shell-script text-processing

我有一个像这样的名字列表:

dog_bone
dog_collar
dragon
cool_dragon
lion
lion_trainer
dog
Run Code Online (Sandbox Code Playgroud)

我需要提取出现在其他名称中的名称,如下所示:

dragon
lion
dog
Run Code Online (Sandbox Code Playgroud)

我查看了uniq手册页,但它似乎比较了整行,而不是字符串。有没有办法用 bash 函数来做到这一点?

Sté*_*las 5

file=/the/file.txt
while IFS= read -r string; do
  grep -Fe "$string" < "$file" | grep -qvxFe "$string" &&
    printf '%s\n' "$string"
done < "$file"
Run Code Online (Sandbox Code Playgroud)

这会在文件的每一行运行一个read、两个grep甚至一个printf命令,因此效率不会很高。

您可以在一次awk调用中完成整个事情:

awk '{l[NR]=$0}
     END {
       for (i=1; i<=NR; i++)
         for (j=1; j<=NR; j++)
           if (j!=i && index(l[j], l[i])) {
             print l[i]
             break
           }
     }' < "$file"
Run Code Online (Sandbox Code Playgroud)

虽然这意味着整个文件都存储在内存中。


gle*_*man 5

猛击

names=(
  dog_bone
  dog_collar
  dragon
  cool_dragon
  lion
  lion_trainer
  dog
)

declare -A contained                 # an associative array
for (( i=0; i < ${#names[@]}; i++ )); do 
    for (( j=0; j < ${#names[@]}; j++ )); do 
        if (( i != j )) && [[ ${names[i]} == *"${names[j]}"* ]]; then
            contained["${names[j]}"]=1
        fi 
    done
done
printf "%s\n" "${!contained[@]}"    # print the array keys
Run Code Online (Sandbox Code Playgroud)
dog
dragon
lion
Run Code Online (Sandbox Code Playgroud)