як перейменувати файли під час копіювання?


12

Як би я скопіював (стиль архіву, коли дата не змінена) всі файли в каталозі резервного копіювання в каталог користувача, перейменувавши кожен файл, щоб видалити випадкову частину рядка з імені (тобто, -2b0fd460_1426b77b1ee_-7b8e)?

cp від:

/backup/path/data/Erp.2014.02.16_16.57.03-2b0fd460_1426b77b1ee_-7b8e.etf

до:

/home/user/data/Erp.2014.02.16_16.57.03.etf

Кожен файл завжди починатиметься з "Erp". Далі слід рядок штампу дати та часу, а потім - випадковий рядок, а потім розширення ".etf". Я хочу зберегти всі елементи імені, включаючи штамп дати та часу. Я просто хочу видалити випадкову рядок.

Випадкова рядок дозволяє зробити декілька резервних копій одного файлу. Однак у цьому випадку я просто запустив fdupes і дублікатів немає. Тому я можу просто відновити всі файли, видаливши випадкову рядок.

Я шукаю однолінійну команду bash для цього.

Якщо це не вийде, я можу зробити це в два чи більше кроків. Я зазвичай використовую KRename, але в цьому випадку мені потрібно це робити в bash. (Я працюю віддалено.)

Відповіді:


7

paxможна зробити це все відразу. Ви можете зробити:

cd /backup/path/data && pax -wrs'/-.*$/.etf/' Erp*etf /home/user/data

paxзберігає часи за замовчуванням, але може додавати, -peщоб зберегти все (найкраще робити як root) або -ppзберегти дозволи, наприклад:

cd /backup/path/data && pax -wrs'/-.*$/.etf/' -pe Erp*etf /home/user/data

Інакше ( paxзазвичай не доступно за замовчуванням), безумовно, краще зробити копію, а потім rename:

cp -a /backup/path/data/Erp*.etf /home/user/data
rename 's/-.*$/.etf/' /home/user/data/Erp*.etf

Таким чином, для кожного файлу не починається інший процес.


1
Я бачу, що мені потрібно ознайомитися pax. Це виглядає як дуже корисний інструмент. Мене здивує, чому це не стандарт у більшості дистрибутивів ...
MountainX

@MountainX, Добре запитання, згідно з Вікіпедією, paxє у стандартній базі Linux з 2005 року. Крім того, альтернативою для цього є GNU cpio- це, мабуть, найменш функціональний інструмент GNU, який існує.
Graeme

1
+1 за ваше останнє рішення. Таким чином, для кожного файлу не починається інший процес. Але rename Fedora / Red Hat відрізняється: я не знаю, як це використовувати в цьому випадку.
erik

15

Ви можете використовувати cpкоманду з -aопцією

-a, --archive
       same as -dR --preserve=all

А потім використовуйте цикл для перейменування всіх файлів під час їх копіювання:

for file in Erp*etf; do
  cp -a $file destinationDirectory/${file%%-*}.etf
done

Готовий. Запустіть цю команду у вихідному каталозі.

Пояснення: The %%-*обріже всі символи після першого появи дефісу / мінусу, -а .etfв кінці знову додається розширення файлу.

Ну, і як один лайнер, покладіть це все в один рядок. :-) Подобається це

for file in Erp*etf; do cp -a $file destinationDirectory/${file%%-*}.etf; done

1
Дякую, ви можете, будь ласка, цитувати документацію для %%-*поради? Мені цікаво.
союка

3

В zsh, використовувати zmv. Помістіть це у своєму .zshrc:

autoload -U zmv
alias zcp='zmv -C'
alias zln='zmv -L'

Потім використовуйте

zcp '/backup/path/data/(*)-[0-9A-Fa-f_]#.(*)' '/home/user/data/$1$2'

В bash:

zsh -c 'autoload zmv; zmv -C $0 $1' '/backup/path/data/(*)-[0-9A-Fa-f_]#.(*)' '/home/user/data/$1$2'

Якщо у вас немає zsh, спосіб POSIX використовує pax (це копіює каталоги рекурсивно).

Якщо ви користуєтесь обмеженою системою без zsh і no pax, ви можете використовувати цикл:

for source in /backup/path/data/*-*.etf; do
  basename=${source##*/}
  cp "$source" "/home/user/data/${basename%-*}.${basename##*.}"
done

1

cpне має такої можливості. Я пам'ятаю, cpioщо міг це зробити, але поточна сторінка повідомляє про інше. Однак у (gnu) tarє --transformваріант:

 --transform, --xform EXPRESSION
       use sed replace EXPRESSION to transform file names

Таким чином, у вас буде cmdline типу:

(cd /backup/path/data; tar --create --transform 's/-.*-....//' .) | (cd /home/user/data; tar --extract)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.