Bash проверяет, частично ли строка file1 содержится в строке из file2

#bash #file #iteration #contains

#bash #файл #итерация #содержит

Вопрос:

У меня есть file1 с идентификаторами и file2, который представляет собой список с полными именами всех файлов в папке.

Идентификаторы из file1 выглядят следующим образом: P001A, P001I, P002A, P002I … И имена файлов из file2 содержат эти идентификаторы сами по себе. Я хочу создать новый file3, который содержит все полные имена из file2, которые имеют идентификаторы из file1.

В File2 около 100 тыс. строк, в то время как в file1 89, так что есть много строк из file2, которые содержат тот же идентификатор из строки в file1.

Это скрипт, который я использую, но он говорит

FILE1: команда не найдена FILE2: команда не найдена -bash: ${FILE1}: неоднозначное перенаправление

   1#!/bin/sh
  2 FILE1 ="$1"
  3 FILE2 ="$2"
  4 while read -r value1
  5 do
  6     while read -r value2
  7     do
  8         if [[ "$value1" == *"$value2"* ]]
  9             then
 10             echo $value2
 11         fi
 12     done <${FILE2}
 13 done <${FILE1} > file3.list
  

Что здесь не так? И знаете ли вы, должен ли этот сценарий быть таким, или я должен сделать какой-то другой способ.

Комментарии:

1. Взгляните на shellcheck.net , он расскажет вам о множестве распространенных ошибок. С места в карьер: вы используете /bin/sh , но затем [[ ... ]] используете Bashism; либо переключитесь на case для сопоставления с образцом, либо используйте /bin/bash (или /usr/bin/env bash ). Затем ваши назначения FILE1 и FILE2 не должны содержать пробелов вокруг = . Наконец, это будет очень медленно, вы можете сделать то же самое с grep -Ff "$FILE2" -- "$FILE1" .

2. Можете ли вы добавить несколько примеров извлечений из двух файлов, а также ожидаемый результат.

3. @BenjaminW. Что делает параметр -Ff ? @ Raman Sailopal в file2 есть, например, файлы от P001A0001 до P001A0120, в то время как в file1 есть только P001A, и я хочу сохранить все файлы, содержащие идентификатор P001A, в третьем файле.

4. @PetarYakov: Пожалуйста, добавьте образцы данных из обоих рассматриваемых файлов

5. -F , -f

Ответ №1:

как сказал @Benjamin — вы используете /bin/sh, но используете «[[» и «]]» для тестирования. Я переписал ваш код, чтобы использовать /bin/sh:

 #!/bin/sh
is_substring(){
    case "$2" in
        *$1*) return 0;;
        *) return 1;;
    esac
}

FILE1="$1"
FILE2="$2"
while read -r value1
do
    while read -r value2
    do
        if is_substring "$value1" "$value2"
            then
            echo $value2
        fi
    done <${FILE2}
done <${FILE1} > file3.list
  

для bash:

 #!/bin/bash
FILE1="$1"
FILE2="$2"
(while read -r value1
do
    (while read -r value2
    do
        if [[ -z "${value2##*$value1*}" ]]
            then
            echo $value2
        fi
done) < ${FILE2}
done <${FILE1}) > file3.list
  

Комментарии:

1. О, это моя ошибка, я должен использовать /bin/bash . Каким тогда будет синтаксис?

Ответ №2:

Я решил свою проблему с помощью этого скрипта

   1#!/bin/bash
  2 for i in $(cat file1);
  3 do
  4    FILENAME=$(find /directory/ -regextype posix-egrep -regex ".*/20170001${i}[0-9]*.wav")
  5    echo "${FILENAME}";
  6 done > file3
  

Мне даже не нужен файл с именами файлов.