Переместить файлы из списка в каталог, названный в честь файла списка

#linux #bash

#linux #bash

Вопрос:

Я просмотрел stackflow, и кажется, что этот вопрос задается довольно часто, но он не совсем отвечает на мой вопрос.

У меня есть 4 текстовых файла с именами 1.txt to 4.txt и 4 каталога с именами 1 to 4 . Внутри каждого txt файла находится список имен файлов:

 ==> 1.txt <==
A.fa
B.fa
C.fa


==> 2.txt <==
D.fa
E.fa
F.fa

==> 3.txt <==
G.fa
H.fa
I.fa


==> 4.txt <==
J.fa
H.fa
L.fa
  

fa Файлы и txt архивы находятся в том же каталоге, что и 4 подкаталога.

Я хочу переместить fa файлы, перечисленные в txt файлах, в каталоги, названные в честь файла, в котором они перечислены.

Так что A.fa B.fa C.fa переместился в 1 и т.д.

Я пробовал это:

 for file in *.txt; do 
    basename=${file%.txt}
         while IFS= read -r file; do 
         mv -v "$file" "$basename/$file"
    done
done
  

Кажется, что он останавливается и ничего не делает, поэтому я завершаю команду. У меня такое ощущение, что моя проблема связана с $basename и, возможно, Linux не распознает $basename имя каталога.

Любая помощь будет оценена. Спасибо

Комментарии:

1. while IFS= read -r file; do не читает ни из чего (т. е. он считывает данные со стандартного ввода). Фактически считывается из файла while IFS= read -r file; do... done <"$file"

2. спасибо, это сработало

Ответ №1:

Вы забыли перенаправить ввод while read цикла из файла, содержащего список имен файлов.

Кроме того, вы используете одну и ту же переменную file в основном for цикле и во внутреннем read .

 for file in *.txt; do 
    basename=${file%.txt}
    while IFS= read -r innerfile; do 
        mv -v "$innerfile" "$basename/$innerfile"
    done < "$file"
done
  

Ответ №2:

Это можно сделать с помощью следующего однострочника Perl:

 perl -lne '( $dir = $ARGV ) =~ s{.txt}{}; $cmd = "mv $_ $dir"; print $cmd; system $cmd and die $?;' [1-4].txt

  

Однострочник Perl использует эти флаги командной строки:
-e : Указывает Perl искать код в строке, а не в файле.
-n : Повторите ввод по одной строке за раз, назначив ее $_ по умолчанию.
-l : Удалите разделитель строк ввода ( "n" по умолчанию * NIX) перед выполнением кода в строке и добавьте его при печати.

$ARGV : текущее имя файла.

СМОТРИТЕ ТАКЖЕ:

perldoc perlrun : как запустить интерпретатор Perl: переключатели командной строки
perldoc perlvar : Предопределенные переменные Perl