Ksh увеличивает аргумент цикла while

В Ksh у меня есть цикл while, который читает 2 файла. Если текущая строка файла 1 - «Y», то отобразить текущую строку файла 2 в новый файл, а если текущая строка файла 1 - «N», отобразить «отходы» в winscp.

    while IFS= read xxxx && IFS= read yyyy <&4; do
if [[ ${xxxx} = "N" ]];then
      echo waste
   else
      echo "$yyyy" .>> $newfile
   fi
done <"$file1" 4<"$file2"

Но если в файле 1 первые три строки обозначены как N, а оставшиеся семь - как Y, вместо трехкратной печати «отходов» и последних семи строк второго файла в новый файл мой Winscp отображает 10-кратные «отходы» при выполнении сценария. .

Пожалуйста, прочтите При каких обстоятельствах я могу добавить к своему вопросу «срочно» или другие похожие фразы, чтобы получить более быстрые ответы? - вкратце, это не идеальный способ обращения к волонтерам и, вероятно, контрпродуктивно для получения ответов. Пожалуйста, воздержитесь от добавления этого к своим вопросам.

halfer 30.10.2018 20:09

Воспроизвести проблему не удалось. Я не знаю, почему. У вас есть специальные входные файлы, работает ли ksh иначе, чем мой bash, или вы сделали чрезмерное упрощение в этом примере. Предоставление входных файлов может помочь.

Walter A 30.10.2018 20:15

Пожалуйста, проверьте мой последний ответ на ваш ответ мне

Gowtham Sarathy 31.10.2018 05:50
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
335
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Предполагая, что в файлах file1 и file2 одинаковое количество строк И что каждая строка файла file1 имеет значение N или Y, вы можете использовать что-то вроде этого:

    #!/bin/ksh

    testArray=($(cat file1.txt))

    i=0

    while read line; do
        if [[ ${testArray[$i]} == "N" ]]; then
            print "waste"
        else
            print $line >> file3.txt
        fi
        ((i++))
    done < file2.txt

Или следующие комментарии

    #!/bin/ksh


    while read -r -u 3 line1 && read -r -u 4 line2; do
            if [[ $line1 == "N" ]]; then
                    print "waste"
            else
                    print $line2 >> file3.txt
            fi
    done 3<file1.txt 4<file2.txt

Работает с моими (очень) небольшими тестовыми файлами ...

Привет, Андре. Спасибо за ответ. Я также подумал о методах массива. Но фактические строки файла могут достигать миллиарда строк (равных для обоих файлов). Имеет ли массив возможность хранить большое количество индексов.

Gowtham Sarathy 30.10.2018 19:52

Это зависит, но 4194303 - это обычный максимальный индекс в кш93. Когда вы говорите «миллиард» ... вы имеете в виду «много» или буквально? С другой стороны, я не думаю, что у bash есть реальный максимум экономии для объема памяти (но не цитируйте меня по этому поводу;))

Andre Gelinas 30.10.2018 20:17

@GowthamSarathy Я добавил новый, который, согласно вашему комментарию, похоже, работает.

Andre Gelinas 30.10.2018 20:36

Привет, Андре. Я пробовал второй вариант. Но все же результаты такие же, как то, что я упомянул в основном вопросе. Я сделал file1 с 10 строками (NYYNYYYYYN), поэтому я должен был получить 7 записей из file2 в file3 и 3 раза «потратить», но я получил только 10-кратный «мусор».

Gowtham Sarathy 31.10.2018 05:07

Поскольку он отлично работает на моей стороне, может быть, это ваш файл2 (мой файл2 содержит только номер в строке)? Вы можете привести пример линий? И, чтобы быть уверенным, вы только с этим кодом не тестировали ничего другого?

Andre Gelinas 31.10.2018 13:36

Привет, Андре. Теперь это сработало. В файле 1 обнаружил строку с пустым пространством. После удаления работает. Спасибо.

Gowtham Sarathy 01.11.2018 20:25

Рад это слышать. Пожалуйста, подумайте о выборе ответа, чтобы люди знали, что вы его больше не ищете. Хороший день !

Andre Gelinas 01.11.2018 20:31

Я отметил ваш ответ как правильный, поскольку он работал нормально. ВТОРОЙ ВАРИАНТ в вашем ответе - жизнеспособный путь. Также использование массива, как в FIRST OPTION, отлично работает, но в некоторых системах есть ограничения на размер массива, поэтому я предлагаю второй вариант в ваших кодах ответов.

Gowtham Sarathy 07.11.2018 11:39

Не вижу в чем проблема. Возможно, в file1 после «N» есть другие символы, например пробел N, другие символы NO или \r (файл Windows). Или строчный n.

Другое решение - использовать paste. Найдите символ, которого нет в файле file1 (например, #), и используйте этот символ для вставки двух файлов вместе. И протестируйте решение с 10 строками, а не с миллиардом (комментарий к другому ответу).

paste -d'#' file1 file2

Возможно, вы заметили что-то странное в строках, которые должны начинаться с N#. Теперь вы можете использовать sed для линий печати p или записи w в файл.

paste -d'#' file1 file2 | sed -n 's/^N#.*/waste/p;s/^[^#]*#//w newfile'

Хай. Я запуталась с ответом. Позвольте мне показать вам пример файлов и ожидаемый результат.

Gowtham Sarathy 30.10.2018 23:03

Вы можете использовать printf "%s\n" N Y Y > file1; printf "%s\n" 1Content 2Content 3Content > file2 для создания тестовых файлов и запускать команды paste. В новом файле newfile должны быть 2 желаемых строки, один раз «отбрасываемые» на стандартный вывод.

Walter A 30.10.2018 23:20

Привет, Уолтер. Если вас смущает мой сценарий, позвольте мне однажды объяснить вам. файл 1 (Он будет там, нам не нужно его создавать) (Каждый символ в новой строке) YYN Файл 2 (Уже доступен) (Каждый в каждой строке) 1Content 2Content 3Content Output Expected: (каждый в новой строке) New file: 1Content 2Content и третья итерация печатает "отходы"

Gowtham Sarathy 31.10.2018 04:52

Могу я еще раз объяснить мне два ваших кода в ответ. Я не понимаю этого ясно.

Gowtham Sarathy 01.11.2018 20:26

Сначала посмотрите на результат paste -d'#' file1 file2 (замените file1 и file2 фактическими именами файлов). Результатом будут строки, начинающиеся с N# или Y#. С sed вы можете заменить строки, начинающиеся с N#, на waste. Возможно, сначала посмотрите на paste -d'#' file1 file2 | sed -n 's/^[^#]*#//p, где отходы игнорируются, а первая часть других строк (до первого #) удаляется.

Walter A 01.11.2018 21:31

Другие вопросы по теме