Вот более эффективный способ сделать то, что вы пытаетесь сделать. Я использую меньший набор образцов, чтобы все было понятнее :
.#!/bin/bash
# clear placeholder
printf "Files with no diff:\n" > placeholder
# set up sample data
echo "one" > file.00.txt
echo "one" > file.01.txt
echo "foo" > file.02.txt
echo "bar" > file.03.txt
echo "two" > file.04.txt
echo "two" > file.05.txt
# generate array
i=0
while [ $i -lt 6 ]; do
array+=( file.`printf %02d $i`.txt )
((i++))
done
i=0
while [ $i -lt 5 ]; do
diff --brief ${array[i]} ${array[i+1]} && \
echo "${array[i]} ${array[i+1]}" >> placeholder
((i++))
done
Результаты:
$ sh./test.sh
Files file.01.txt and file.02.txt differ
Files file.02.txt and file.03.txt differ
Files file.03.txt and file.04.txt differ
$ cat placeholder
Files with no diff:
file.00.txt file.01.txt
file.04.txt file.05.txt
Вам не нужно генерировать образцы данных, если у вас уже есть данные.
Объяснение кода:
Построение массива в цикле (в Bash )может быть выполнено путем итерации, как вы, очевидно, уже знаете, но нотация array+=
добавляет элемент.
Очевидно, ((++))
увеличивает ваш счетчик.
Выполняя diff, я использую опцию --brief
. Если вы читаете справочную страницу diff
, там сказано, что --brief
выводит вывод только при обнаружении различий. Следовательно, команда diff завершается успешно , если diff не найден.
Используя нотацию&&
(И ), этот код повторяет имена сравниваемых файлов в вашем файле placeholder
тогда и только тогда, когда команда diff
не генерирует выходных данных.
Если есть разница между файлами , diff
выводит различия на терминал. Это приводит к сбою&&
(И ), поэтому в файл-заполнитель ничего не выводится.
Если у вас есть дополнительные вопросы по синтаксису, не стесняйтесь спрашивать.
На любом устройстве, совместимом с POSIX awk
, вы можете использовать функцию tolower()
awk -v FS='=' 'BEGIN { OFS = FS } { $2 = tolower($2) }1 ' file
Используйте функцию mktemp()
для создания временного файла для перенаправления вывода вышеприведенной команды, а затем повторно -перенаправления обратно для сохранения в -месте. Или используйте GNU awk
>= 4.1 с-i inplace
Другой вариант версии, совместимой с POSIX, с использованием функции match()
будет выполнять
awk 'match($0, /=([^,]*),/) { str = substr($0, RSTART+1, RLENGTH-2); sub(str, tolower(str)) }1'
Это возможно с GNU sed. Выберите одну из этих двух форм, исходя из жадности замены.
sed 's|=.*,|\L&|' file
sed 's|=[^,]*,|\L&|' file
Как указано в руководстве , «\L
переводит замену в нижний регистр до тех пор, пока не будет найдено \U
или \E
». &
— это текст, соответствующий регулярному выражению.
Я изменил образец файла, чтобы показать, что вы должны разумно выбирать между жадными =.*,
и не -жадными =[^,]*,
регулярными выражениями:
$ cat file
SOMENAME=WOODSTOCK,
SOMEOTHERNAME2=JIMMY,WOODSTOCK,FINISH
$ sed 's|=.*,|\L&|' file
SOMENAME=woodstock,
SOMEOTHERNAME2=jimmy,woodstock,FINISH
$ sed 's|=[^,]*,|\L&|' file
SOMENAME=woodstock,
SOMEOTHERNAME2=jimmy,WOODSTOCK,FINISH