Як ви використовуєте регулярні вирази з командою cp в Linux?


22

Я намагаюся скопіювати лише підмножину файлів з одного каталогу в інший, використовуючи, cpпроте, я вітаюсь із цим повідомленням cp: cannot stat [^\.php]': No such file or directory. Чи є спосіб використовувати регулярні вирази лише за допомогою cpкоманди?

Відповіді:


27

Немає.

cpКоманда не має здатності обробляти будь-якого з його аргументів в вигляді регулярних виразів. Навіть макіяжі не обробляються ним (або більшістю виконуваних файлів); скоріше вони обробляються оболонкою.

cp test/* test2/насправді розширений bash, і все, що cpдійсно бачить для своїх аргументів, є cp test/file1 test/file2 test/file3 test2/(або все, що підходить, виходячи з фактичного змісту test/).

Крім того, я не думаю, що ваш вираз, [^\.php]буде відповідати тому, що ви хочете (воно не відповідає лише тим файлам, які містять .php).

Ви, мабуть, хочете заглянути в findутиліту для фільтрації списку файлів на основі регулярного вираження, а потім використати xargsдля застосування списку повернених файлів до cpкоманди (припускаючи, що знахідка не має вбудованого обробника для копіювання файлів; я ' м не дуже знайомий з інструментом).

Ви можете спробувати:

find . ! -iregex ".*\.php.*" -exec cp {} /destination/folder/ \;

Це говорить про пошук у поточному каталозі рекурсивно для файлів, які не містять ".php" у шляху, та копіювання в них /destination/folder/.

Як вимагається, більш конкретна розбивка аргументів:

  • . - Місце для початку пошуку - у цьому випадку поточний каталог
  • ! - Оператор "Не", переверніть результат наступного тесту
  • -iregex- Тест регулярної експресії на нечутливий до випадків. Наступний аргумент - вираз.
  • ".*\.php.*"- Відповідність регулярних виразів <Anything>.php<Anything>- будь-який файл, який має ".php" десь на шляху. (Зверніть увагу, якщо ви знаходитесь у папці, яка містить ".php" в імені, вам знадобиться більш складний вираз, щоб відповідати лише файлам)
  • -exec- Виконайте команду, якщо попередні тести повертають істину. Наступним аргументом є команда, всі решта аргументів до ;цього передаються команді. {}це особливий аргумент , який представляє ім'я файлу.
  • cp - Команда, що find` повинна виконуватись на кожному зі збігованих імен шляху.
  • {}- Шлях до знайденого файлу передається cpяк аргумент, щоб він знав, у який файл скопіювати
  • /destination/folder/- переданий аргумент cp, вказуючи, cpкуди він повинен скопіювати файл.
  • \;- Це той ;термінатор, який -execшукають. Ми уникаємо його з \тим, щоб ваша оболонка не намагалася розібрати її, а замість цього подала як аргумент команді ( find)

Досить складно написати регулярний вираз, який відповідає "рядкам, яких немає .php", тому ми замість цього радимо findшукати рядки, які містять, .phpа потім обернути результати !.


2
find . -name [^\.php] -exec cp {} /path/to/location \;будьте уважні до файлів із спеціальними символами.
Роб

@Darth Android - спасибі Я не знав, що cpта інші двійкові файли не в змозі розгорнути регулярні вирази. Ви б проти зауважити, що означає кожен із варіантів та аргументів у прикладі, який ви наводили? Я знаю , що .відноситься до поточної директорії , але що робити !, {}, \;і т.д. см , а також те , що вони означають? Наприклад, навіщо вам бігти ;?
АрахісМонкі

@Rob - Що ви маєте на увазі під спеціальними файлами?
АрахісМонкі

@Rob - я спробував подібним виразом видалити конкретні файли, проте в кінцевому підсумку видалив усі файли в каталозі. find . -name '[^\.txt]' -exec rm {} \;Звідси моя команда - це моє небажання використовувати find. Можливо, з мого боку помилка, але я не впевнений, що я зробив неправильно. Наскільки я розумію, це {}стосується кожного файлу, знайденого командоюfind . -name '[^\.txt]'
PeanutsMonkey

Що ви намагаєтеся співставити з регулярним виразом?
Роб

9

Ви можете використовувати небагато інших інструментів з консолі, таких як grep та xargs.

ls -1 some_folder | egrep 'some_extended_regex' | xargs cp -t destination_folder

Чим він {}відрізняється від цього -t?
PeanutsMonkey

2
У цьому випадку не багато. Альтернативним синтаксисом для xargs буде "xargs cp {} призначення_папка". стандартний синтаксис cp приймає одне або багато джерел і одне призначення в кінцевому підсумку, коли ви використовуєте -t варіант, ви можете вказати призначення після -t, а потім використовувати решту рядка для джерел. Я просто знаходжу варіант -t більш зручним в цьому випадку. В іншому прикладі {} замінюється тим, що передається на xargs (stdin), у цьому випадку - ім'я файлу.
0xAF

-1

Ви можете запустити таку команду, просту у використанні:

find /home/usr/search_dir -iname *file_name_portion*.txt | xargs cp -t /home/usr/destination_folder

круто хаа !!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.