Цель сценария, который я создаю, - сравнить две серии файлов. Имена файлов сами хранятся в двух отдельных файлах, по одному пути на строку. Моя идея состоит в том, чтобы иметь два while read
цикла, по одному для каждого списка имен файлов, но как я могу смешать два цикла вместе?
while read compareFile <&3; do
if [[ ! $server =~ [^[:space:]] ]] ; then #empty line exception
continue
fi
echo "Comparing file - $compareFile"
if diff "$compareFile" _(other file from loop?_) >/dev/null ; then
echo Same
else
echo Different
fi
done 3</infanass/dev/admin/filestoCompare.txt
Мне нужно иметь возможность сравнивать файлы из двух разных списков одновременно через два цикла чтения ... Это вообще возможно?
bash
shell-script
control-flow
mkrouse
источник
источник
diff
.diff
.Ответы:
Вам не нужны две петли; вам просто нужно прочитать из двух файлов в одном цикле.
источник
Способ 1: используйте то, что вы знаете
Поскольку вы уже знаете, как перебрать один файл, вы можете объединить файлы и затем обработать объединенные файлы. Команда
paste
объединяет два файла построчно. Он помещает вкладку между строками из двух файлов, поэтому в этом решении предполагается, что в именах файлов нет вкладок. (Вы можете изменить разделитель, но вы должны найти символ, которого нет в имени файла.)Если вы хотите пропустить пустые строки, вам нужно сделать это в каждом файле отдельно, так как
paste
может совпадать пустая строка из одного файла с непустой строкой из другого файла. Вы можете использоватьgrep
для фильтрации непустых строк.Обратите внимание, что если два файла имеют разную длину, вы получите пустой
$file2
(независимо от того, какой список закончился первым).Способ 2: зациклить два файла
Вы можете поместить любую сложную команду в состояние цикла while. Если вы поставите,
read file1 <&3 && read file2 <&4
цикл будет выполняться до тех пор, пока оба файла будут иметь строку для чтения, т.е. пока не закончится один файл.Если вы хотите пропустить пустые строки, это немного сложнее, потому что вы должны пропустить два файла независимо друг от друга. Самый простой способ - разбить проблему на две части: пропустить пустые строки из одного файла и обработать непустые строки. Один из способов пропустить пустые строки - обработать,
grep
как описано выше. Следите за тем, чтобы между<
оператором перенаправления и тем<(
, кто запускает команду, появилось свободное пространство.Другой метод заключается в написании функции, которая ведет себя как,
read
но пропускает пустые строки. Эта функция может работать, вызываяread
в цикле. Это не обязательно должна быть функция, но функция - лучший подход, как для организации вашего кода, так и потому, что этот фрагмент кода необходимо вызывать дважды. В функции${!#}
это экземпляр конструкции bash,${!VARIABLE}
которая оценивает значение переменной, имя которой равно значениюVARIABLE
; здесь переменная является специальной переменной,#
которая содержит номер позиционного параметра, так же${!#}
как и последний позиционный параметр.источник
-u
опции чтенияОдин подход будет использовать
read -ra
вместо простоread
. Если предположить , чтоfilestoCompare.txt
содержащиеся 2 колонки с именами файлов в каждой, тоread -ra
прочитал бы обе колонки в то же время и назначить их в массив,compareFile
. Затем к этому массиву можно получить доступ, чтобы индекс 0 был первым файлом, а индекс 1 - вторым файлом каждый раз вwhile
цикле.пример
Скажем, у меня есть этот файл:,
filestoCompare.txt
и он содержит следующее:Команда для просмотра этого файла будет выглядеть следующим образом:
Если 2 файла действительно являются отдельными файлами, такими как:
Их можно объединить с помощью
paste
команды следующим образом:Вот содержимое list1and2:
источник
join
их в первую очередь.paste
для объединения двух файлов? Это заставит вас отказаться от голосования?