#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