Избавляемся от символов 000A в именах файлов

Команды fg, job связаны только с интерактивными сеансами и не имеют смысла в пакетном режиме (сценарии).

Технически вы можете включить их с помощью флага -m, но это все равно будет иметь мало смысла (если вообще есть), поскольку это относится только к интерактивным приложениям, в которых вы можете отправлять задания обратно с помощью ^ Z, но поскольку вы не не имеет такого взаимодействия в сценарии оболочки, это делает его бессмысленным.

Практический ответ: нет, нельзя.

1
04.09.2016, 01:29
2 ответа

Проблема в том, что ваши имена файлов содержат новую строку, например aaa \ nbbb , а ваш find | Метод чтения не может отличить это от двух файлов, aaa и bbb .

Обычный ответ на этот вопрос - заставить find разделять имена файлов символом nul \ 0 , используя find -print0 , а затем используя IFS = read -r -d '' FILENAME , чтобы прочитать этот входной поток. -d '' указывает read использовать символ нуля в качестве разделителя строк, -r останавливает обработку обратной косой черты, а IFS = сохраняет пробелы в начале и в конце.

0
27.01.2020, 23:47

На этом рисунке представлен символ, значение 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/ /' {} +
1
27.01.2020, 23:47

Теги

Похожие вопросы