У меня есть некоторые файлы в каталоге следующим образом.
source_dir:
ABCD.HRA.0014.2.200.png
ABCD.HRA.0015.2.200.png
ABCD.HRA.0016.2.200.png
MMNP.HRA.0016.2.200.png
У меня также есть текстовый файл со следующим содержанием.
text.txt:
ABCD.HRA.0014
ABCD.HRA.0015
Теперь есть ли любой способ, в котором я могу передать файлы согласно строке, упомянутой text.txt
. После command
, source dir
и dest_dir
должен быть следующие.
source_dir:
ABCD.HRA.0016.2.200.png
MMNP.HRA.0016.2.200.png
dest_dir:
ABCD.HRA.0014.2.200.png
ABCD.HRA.0015.2.200.png
grep -f
позволяет Вам использовать text.txt в качестве источника для шаблонов.
#!/bin/bash
for i in source_dir/*.png; do
if grep -Fq -f text.txt <<< "$i"; then
mv -t dest_dir "$i"
fi
done
$ ls
dest_dir script.sh source_dir text.txt
grep опции:
-F
Интерпретируют шаблоны как починенные строки, не регулярные выражения. -q
ничего не пишут в stdout. -f
Получают шаблоны из ФАЙЛА, один на строку. Здесь строки:
<<<
вариант А здесь документов, делает переменное расширение прежде, чем отправить строку. опции мВ:
-t
Перемещение все исходные аргументы в -t
каталог. Ваши файлы, которые все, кажется, заканчивают в .2.200.png
, следовательно мы можем использовать входной файл только:
while read line ; do
mv "source_dir/${line}.2.200.png" destination_dir/
done < text.txt
Другой способ использовать находит:
find source_dir -type f | while read file; do name=$(basename $file); grep ${name%.2.200.png} text.txt && mv -v $file dest_dir; done
Находят файл в source_dir
и циклы по списку.
Для каждого файла выполнения grep
в text.txt
. Необходимо получить имя файла с помощью basename
команда для исключения source_dir
папка.
Наконец, если grep
возвращает true, файл перемещений в dest_dir
.
Добавление -v
к [1 110] команда и удаление -q
к команде grep, Вы видите действие.
Вот примеры того, Как использовать его:
$ ls source_dir
ABCD.HRA.0014.2.200.png MMNP.HRA.0016.2.200.png shrr.2.200.png
ABCD.HRA.0015.2.200.png sghd.2.200.png
ABCD.HRA.0016.2.200.png shdj.2.200.png
$ cat text.txt
ABCD.HRA.0014
ABCD.HRA.0015
$ mkdir dest_dir
$ find source_dir -type f | while read file; do name=$(basename $file); grep ${name%.2.200.png} text.txt && mv -v $file dest_dir; done
ABCD.HRA.0014
`source_dir/ABCD.HRA.0014.2.200.png' -> `dest_dir/ABCD.HRA.0014.2.200.png'
ABCD.HRA.0015
`source_dir/ABCD.HRA.0015.2.200.png' -> `dest_dir/ABCD.HRA.0015.2.200.png'
Один путь, если Вы знаете все имена файлов в файле, не содержит пробела, похож на это:
cp $(cat text.txt) targetdir/
я всегда добавляю /
в конце - это делает сбой команды, если targetdir не существует и является каталогом; Вы хотите, чтобы это произошло, потому что иначе можно закончить тем, что копировали все файлы в, каждый звонил targetdir
(на самом деле, я думаю, что этого больше не происходит в современном bash
; я - это старое)
, Если каждая строка в файле содержит одно имя файла, которое может содержать пробел, этот метод работы, по крайней мере, в ksh
и более новые версии bash
:
cat text.txt | while read l
do
cp "$l" targetdir/
done
И если это не работает в Вашей версии bash
, то это делает (отмечают < text.txt
после done
):
while read l
do
cp "$l" targetdir/
done < text.txt
Обновление: j4nd3r53n корректен: этот won’t работает на любые имена файлов, которые содержат пробел. Извинения за мой “senior moment”—, что я предназначил (и часто делали) состояли в том, чтобы передать его по каналу к while
, поскольку я показал после. Я не удалю неправильный, поскольку он может предоставить полезное предупреждение тем, которые могли бы попробовать его.
Еще один дефектный метод (см. предупреждение выше):
for STR in $(cat file); do # flawed
cp "source/*${STR}*" dest
done
Вот метод, который я первоначально имел в виду:
cat file | while read STR # better
cp "source/*${STR}*" dest
done
Немного замысловатый, но Вы могли использовать awk (который в этом случае делает не что иное как чтение вслух файла линию за линией)
awk '{system("mv " [110] "* dest_dir/")}' text.txt
, который в основном говорит 'для каждой строки, сделайте mv BASE_STR* dest/
'
, Но подход очень зависит от Вашего определенного варианта использования, это не могло бы работать, если Вы хотите сделать это более универсальным.