В bash
чтение из каждого файла в цикле while
, сравнение прочитанных строк и печать TRUE
или FALSE
соответствующим образом:
while IFS= read -r -u3 line1; IFS= read -r -u4 line2; do
[[ $line1 == $line2 ]] && echo TRUE || echo FALSE
done 3<file1 4<file2
Два вызова read
считывают из дескриптора файла 3 и 4 соответственно. Файлы перенаправляются на них с двумя входными перенаправлениями в цикле.
Вы можете получить доступ к последнему элементу с помощью${argv[-1]}
(bash 4.2 или выше )и удалить его из массива с помощью unset
встроенной (bash 4.3 или выше):
last=${argv[-1]}
unset 'argv[-1]'
Кавычки вокруг argv[-1]
необходимы, так как [...]
является оператором glob, поэтому argv[-1]
без кавычек может расширяться до argv-
и/или argv1
, если эти файлы существовали в текущем каталоге (или до ничего или вызвать ошибку, если они не были включены nullglob
/ failglob
).
Вы можете немного упростить, чтобы было проще для глаз, но основной метод не изменился (это может быть полезно, если у вас есть версия Bash, которая не поддерживает Предложение Quasímodo):
foo () {
local argv=( "$@" )
local last="${argv[$# - 1]}"
argv=( "${argv[@]:0:$# - 1}" )
echo "last: $last"
echo "rest: ${argv[@]}"
}
Я признаю, что использование $#
таким образом немного дерзко, но оно имеет то же значение, что и${#argv[@]}
в этом конкретном примере , и более лаконично в коде.
Как насчет этого:
foo () {
local last="${!#}"
local argv=("${@:1:$#-1}")
echo "last: $last"
echo "rest: ${argv[@]}"
}
Для записи, в случае, если переключение на zsh
является опцией, в zsh
массив позиционных параметров равен массиву $argv
(массивы zsh являются истинными массивами, а с индексами, начинающимися с единицы, как и позиционные параметры ), так что здесь просто:
foo () {
local last=$argv[-1]
argv[-1]=()
print -rC1 "last: $last" rest: ' - '$^argv
}
Хотя можно было бы и так:
foo () {
print -rC1 "last: $argv[-1]" rest: ' - '$^argv[1,-2]
}
И если конечной целью является перебор позиционных параметров в обратном порядке:
for arg in "${(Oa)@}"; do
something with "$arg"
done
Для более простого эквивалента ответа bxm используйтеset
:
pop() {
last="${!#}" # see man bash, search for "indirect expansion"
set -- "${@:1:$#-1}"
printf 'not last: %s\n' "$@"
printf 'last: %s\n' "${last}"
}
pop 1 2 3 4
# prints:
# not last: 1
# not last: 2
# not last: 3
# last: 4
Здесь ${!#}
— расширение косвенного параметра (поиск «косвенного расширение» в man bash
), а set -- ARGS...
устанавливает новые значения аргументы($1
и т. д. )к заданным аргументам.
Примечательно, что ${!#}
и нарезка массива являются башизмами, но set --
является переносим на любую оболочку POSIX.