Рейтинг:0

Почему переименование файлов с помощью sed и mv печатает '$'\r'

флаг ke

Я использую Ubuntu на машине с Windows 10. Я пытаюсь переименовать 5 файлов (file1.txt, file2.txt, file3.txt, file4.txt, file5.txt), чтобы каждый файл был заменен на Sample#_VoucherID.fastq.gz.

Для этого у меня есть файл .csv в формате старый файл, новый файл и я использую сед следующее"

sed 's/^/mv -vi /;s/,/ /;s/$//' < File-Rename.csv | баш -е

Всякий раз, когда я запускаю это, я вместо получения:

Sample#_VoucherID.fastq.gz для каждого файла я получаю 'Образец#_VoucherID.fastq.gz'$'\r' вместо. Почему это происходит? Если я использую мв просто в терминале Ubuntu, чтобы переименовать файлы, я переименовываю файлы, как хочу, без ',$\ до и после имени файла. Если я не использую | баш -е в файле и я удаляю кавычки, он печатает:

mv -vi file1.txt Sample1_VoucherID.fastq.gz

mv -vi file2.txt Sample2_VoucherID.fastq.gz

mv -vi file3.txt Sample3_VoucherID.fastq.gz

mv -vi file4.txt Sample4_VoucherID.fastq.gz

mv -vi file5.txt Sample5_VoucherID.fastq.gz

однако на самом деле он не запускает мв команда. Как я могу переименовать свои файлы, не получая эти лишние символы?

флаг cn
Поскольку файл File-Rename.csv имеет окончание строки `\r\n` в стиле DOS. Используйте на нем `dos2unix` или выполните `sed -e 's/\r$//' -e 'ваш код здесь'`
Рейтинг:2
флаг hr

Это происходит потому, что ваш входной файл Файл-Rename.csv имеет окончание строки CRLF в стиле Windows вместо стиля Unix НЧ - $'\r' это способ представления символа возврата каретки в оболочке.

Вы можете «исправить» свою команду, изменив окончательное выражение sed с с/$// (который на самом деле ничего не делает - $ в регулярном выражении — это утверждение нулевой длины, которое соответствует концу строки, но фактически не использует символ) для с/\r$//

В качестве альтернативы конвертируйте входной файл, используя dos2unix

ОДНАКО этот подход к переименованию файлов проблематичен - в частности, он не удастся, если старое или новое имя содержит пробелы или определенные специальные символы оболочки - и даже допускает внедрение кода1. Вместо этого я бы предложил что-то вроде

в то время как IFS=, читать старый новый; делать 
  mv -vi -- "$ старый" "$ новый"
сделано < <(sed 's/\r$//' File-Rename.csv)

или же

в то время как IFS=, читать старый новый; делать 
  echo mv -vi -- "$old" "${new%$'\r'}"
сделано < File-Rename.csv

(удалить эхо как только вы будете довольны предложенными командами).

Обратите внимание, что этот подход сам по себе не работает для определенных имен, допустимых в формате CSV, в частности тех, которые содержат встроенные запятые в кавычках ("фу, бар", баз Например).


1 подумайте, что произойдет, если кто-то введет имя файла, например foo;rm * Например

Justin avatar
флаг ke
Спасибо! Это сработало! Насколько мне известно, что делал `s/\r$\`? Это говорит о том, чтобы заменить `CRLF` ничем? Это сработало! Я не использую пробелы, поэтому я воспользовался первым предложением, но я также буду помнить о коде while, который вы отправляете. Я ценю его!
флаг hr
@Justin Да, верно - `sed 's/\r$//'` соответствует символу возврата каретки `\r`, привязанному к концу строки `$`, и ничего не заменяет на его месте. Вероятно, вы могли бы безопасно удалить *все* возвраты каретки (например, с помощью `tr -d '\r'`), но версия sed более формально подходит для преобразования CRLF в LF.
Justin avatar
флаг ke
Спасибо; это действительно полезно, потому что когда я пытался использовать `dos2unix`, это не помогало; так что знать альтернативные коды, как вы дали, здорово. Я также ценю, что вы нашли время, чтобы объяснить код!

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.