копирование файлов со строкой на их имя от одной папки до другого

У меня есть некоторые файлы в каталоге следующим образом.

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
9
задан 11 November 2019 в 03:30

6 ответов

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 каталог.
11
ответ дан 23 November 2019 в 04:46

Ваши файлы, которые все, кажется, заканчивают в .2.200.png, следовательно мы можем использовать входной файл только:

while read line ; do
  mv "source_dir/${line}.2.200.png" destination_dir/
done < text.txt
9
ответ дан 23 November 2019 в 04:46

Другой способ использовать находит:

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'
3
ответ дан 23 November 2019 в 04:46

Один путь, если Вы знаете все имена файлов в файле, не содержит пробела, похож на это:

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
3
ответ дан 23 November 2019 в 04:46

Обновление: 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
3
ответ дан 23 November 2019 в 04:46

Немного замысловатый, но Вы могли использовать awk (который в этом случае делает не что иное как чтение вслух файла линию за линией)

awk '{system("mv " [110] "* dest_dir/")}' text.txt 

, который в основном говорит 'для каждой строки, сделайте mv BASE_STR* dest/'

, Но подход очень зависит от Вашего определенного варианта использования, это не могло бы работать, если Вы хотите сделать это более универсальным.

2
ответ дан 23 November 2019 в 04:46

Другие вопросы по тегам:

Похожие вопросы: