bash: команда чтения игнорируется в цикле - PullRequest
0 голосов
/ 19 сентября 2019

Я использую небольшой код, чтобы проверить, совпадают ли некоторые файлы друг с другом, а затем вывести вопрос пользователю и предпринять соответствующие действия в соответствии с ответом пользователя.Однако bash полностью игнорирует мою команду чтения!

declare -i int
int=1
find ./1 -name '*.xyz' | while read FILENAME
do
find . -name '*.xyz' | while read FILENAME2
do
    if [ $FILENAME != $FILENAME2 ]; then
        if [ $(dirname "${FILENAME}") != $(dirname "${FILENAME2}") ]; then
            if [ $(basename "${FILENAME}") == $(basename "${FILENAME2}") ]; then
                int=int+1
                if cmp -s "$FILENAME" "$FILENAME2" ; then
                    echo "Match", "$FILENAME", "$FILENAME2", "$int"
                else
                    # echo "No Match", "$FILENAME", "$FILENAME2", "$int"
                    read -p "No match modify? (y/n)" d
                    echo "$d ";
                fi
                if [ "$int" -gt 44 ]; then
                    exit 1
                fi
            fi
        fi
    fi
done
done 

Я использую osx.Я проверил, и простая команда чтения правильно работает вне цикла на моем терминале (iterm).

1 Ответ

1 голос
/ 19 сентября 2019

Весь цикл while имеет стандартный перенаправленный вход.Любой read будет использовать одну строку ввода из find вместо терминала пользователя.

Многократное выполнение одной и той же команды find во внешнем цикле в любом случае ужасно неэффективно.Вероятно, соберите результаты двух команд find в два массива, а затем просто зацикливайте строки в памяти вместо того, чтобы крутить диск по одним и тем же каталогам снова и снова.

Однако, если вы пытаетесь найтифайлы вне 1, которые идентичны файлам в 1 с тем же именем, гораздо более эффективный подход состоит в том, чтобы запустить

find . -name '*.xyz' -exec shasum {} +

, а затем обработать итоговый вывод в простом сценарии Awk.Возможно, что-то вроде этого:

#!/bin/bash

find . -name '*.xyz' -exec shasum {} + |
# Reverse each line, sort by first field, reverse again
# Entries for files with the same basename will now be adjacent
rev | sort -t / -k1,1 | rev |
awk -F / '$NF!=p { p=$NF; delete a; c=""; }
    { split($0, x, /[ \t]+/);
        if(x[2] ~ /^\.\/1\//) { 
            if (a[x[1]]) print a[x[1]];
        c = x[1];
            next
        }
        if (c) {
            if (x[1] == c) print x[2];
            next;
        }
        a[x[1]] = x[2] (a[x[1]] ? ORS a[x[1]] : ""); }'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...