#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: Пожалуйста, добавьте образцы данных из обоих рассматриваемых файлов
Ответ №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
Мне даже не нужен файл с именами файлов.