Команды fg, job связаны только с интерактивными сеансами и не имеют смысла в пакетном режиме (сценарии).
Технически вы можете включить их с помощью флага -m, но это все равно будет иметь мало смысла (если вообще есть), поскольку это относится только к интерактивным приложениям, в которых вы можете отправлять задания обратно с помощью ^ Z, но поскольку вы не не имеет такого взаимодействия в сценарии оболочки, это делает его бессмысленным.
Практический ответ: нет, нельзя.
Проблема в том, что ваши имена файлов содержат новую строку, например aaa \ nbbb
, а ваш find | Метод чтения
не может отличить это от двух файлов, aaa
и bbb
.
Обычный ответ на этот вопрос - заставить find
разделять имена файлов символом nul \ 0
, используя find -print0
, а затем используя IFS = read -r -d '' FILENAME
, чтобы прочитать этот входной поток. -d ''
указывает read использовать символ нуля в качестве разделителя строк, -r
останавливает обработку обратной косой черты, а IFS =
сохраняет пробелы в начале и в конце.
На этом рисунке представлен символ, значение Unicode которого равно 000A (в шестнадцатеричном формате). Это символ перевода строки (LF) , то есть разрыв строки.
Linux допускает разрывы строк в именах файлов, но это очень необычно. Можно обрабатывать имена файлов с разрывами строк в сценариях оболочки, но вам нужно быть особенно осторожным. Ваш сценарий анализирует вывод find
, и, поскольку этот вывод использует символы новой строки для разделения элементов, этот метод по сути не может обрабатывать новые строки в именах файлов.
Ваш сценарий намного сложнее, чем должен быть. Если вы все упростите, это сработает. Как правило, действуйте с данными, когда они у вас есть, вместо того, чтобы упаковывать все в текстовый поток и повторно анализировать его.
С помощью find
не анализировать вывод. Используйте действие -exec
.
Самый простой способ сделать это переименование (я заменю символы новой строки пробелами) - использовать zsh , благодаря его функции zmv
.
autoload -U zmv # put this in your .zshrc
cd $working_dir
zmv '**/*' $'${f//\n/ }'
Если вам действительно нужно придерживаться программ, которые всегда предустановлены на невстроенном Linux, вот простой (хотя и несколько медленный) метод, который использует bash для переименования:
find "$working_dir" -type f -name '*
*' -exec bash -c 'mv "$0" "${0//
/ }"' {} \;
Вы можете ускорить это, вызвав bash для пакетов файлов:
find "$working_dir" -type f -name '
' -exec bash -c 'for x; do mv "$x" "${x//
/ }"' _ {} +
Если есть одна новая строка, в Linux вы можете использовать команду rename
(в Debian и производных версиях она называется rename.ul
).
find "$working_dir" -type f -name '
' -exec rename '
' ' ' {} +
Если у вас есть prename
:
find "$working_dir" -type f -name '
' -exec prename 'y/\n/ /' {} +