Показать статистику
0 голосов
от (2.5тыс. баллов)

Я пытаюсь прочитать имена изображений из текстового файла rgb_train_ids.txt, а затем я перемещу изображения после прочтения их имен в новую папку, которая называется Train.

#!/bin/bash

for file in $(cat rgb_train_ids.txt); do 
     mv "$file.png" "Train"; 
done

Когда я выполняю приведенный выше скрипт bash, он перемещает только второе изображение img_2 и показывает это:

mv: cannot stat 'img_1'$'\r''.png': No such file or directory

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

введите описание изображения здесь

126 просмотров 1 ответов

1 Ответ

0 голосов
от (26.4тыс. баллов)

$'\r' Указывает, что строки в вашем файле rgb_train_ids.txt имеют окончания строк в стиле DOS, состоящие из двухсимвольной последовательности CRLF. Linux ожидает, что файлы будут использовать только LF. Вы можете преобразовать файл с помощью утилиты dos2unix или удалить символы CR с помощью tr или , sed ,например.

Кроме того, использование циклов по строкам for file in $(cat rgb_train_ids.txt) является плохой практикой — если строки содержат пробелы или другие специальные символы оболочки, произойдет сбой. Вместо этого вы должны рассмотреть возможность использования цикла while:

while IFS= read -r file; do
  mv "$file.png" Train/
done < <(tr -d '\r' < rgb_train_ids.txt)

 В качестве альтернативы вы можете  указать mv -t Train "$file.png", что Train это целевой каталог .

 

Вы также можете рассмотреть возможность использования xargs вместо цикла оболочки:

tr -d '\r' < rgb_train_ids.txt | xargs -d '\n' mv -t Train

...