Переименование файлов, содержащих квадратные скобки - PullRequest
1 голос
/ 14 апреля 2019

Команда PS для пакетного переименования файлов в одной папке работает для всех файлов, в которых нет пары квадратных скобок, но никогда, если имя файла содержит ее.Это также работает, если в имени указана одна или несколько правых квадратных скобок, но любое количество левых скобок приводит к ошибке.

Комментарий об ошибке: rni: Невозможно выполнить задание положения'empposition «C: \ Users \ X \ Documents \ dossier \ machine [3] .txt», car il n'existe pas.

перевод _ rni: невозможно переименовать элемент, найденный в «C: \ Users \ X \ documents \ dossier \ machine [3] .txt », так как он не существует.

Вот код команды;

$dos1=(ls C:\Users\X\documents\dos1).name
foreach ($fic in $dos1)
{rni C:\Users\X\documents\dos1\$fic §§$fic}

Пользователь PetSerAI предложение вставить "-LiteralPath" прекрасно работает в данном случае;

$dos1=(ls C:\Users\X\documents\dos1).name
foreach ($fic in $dos1)
{rni -literalpath C:\Users\X\documents\dos1\$fic §§$fic}

Тем не менее, для несколько более сложного кода такая же проблема повторяется;«-LiteralPath» не имеет ожидаемого эффекта в следующем коде;

$dos1=(ls C:\Users\X\documents\dos1).name       
$dos2=(ls C:\Users\X\documents\dos2).name
foreach ($fic2 in $dos2) {foreach ($fic1 in $dos1)
{if ("$fic1" -match "$fic2") {rni -literalpath C:\Users\X\documents\dos1\$fic1 §§$fic1}}}

Хуже того, переименование происходит по крайней мере для одной пары непохожих имен:

" §§§§§§§§Machine 5.txt"," machine 5.txt".

Есть ли способ заставить это работать без слишком большого дополнительного кодирования?

Ответы [ 2 ]

1 голос
/ 15 апреля 2019
  • Как заметил PetSerAl , используйте параметр -LiteralPath для однозначной передачи пути как есть, без потенциально нежелательной интерпретации как * выражения подстановочного знака, потому что это то, что позиционное использование аргумента пути делает из-за неявной привязки к параметру -Path.

  • Аналогично, выне должен использовать -match для выполнения строкового литерала сравнений, поскольку RHS -match по конструкции интерпретируется как регулярное выражение ( регулярное выражение ), где [...] также имеет особое значение, как и в выражениях с подстановочными знаками (хотя важно отметить, что регулярные выражения и подстановочные знаки имеют только отдаленное отношение и обычно имеют принципиально иной синтаксис).

    • Выполнение строки-literal сравнение на равенство , просто используйте -eq.
    • Если вам нужно совпадение строкового литерала , см. этот ответ .

Для этогоe, используйте следующее:

$dos1=(gci -LiteralPath C:\Users\X\documents\dos1).name       
$dos2=(gci -LiteralPath C:\Users\X\documents\dos2).name
foreach ($fic2 in $dos2) {
  foreach ($fic1 in $dos1) {
   if ($fic1 -eq $fic2) { rni -LiteralPath C:\Users\X\documents\dos1\$fic1 §§$fic1 }
  }
}

Примечание. Я заменил ls на более идиоматический псевдоним PowerShell gci для командлета Get-ChildItem (в соответствии с вашим использованием rni дляRename-Item);в целом, однако, лучше вообще избегать псевдонимов в сценариях.

Также обратите внимание, что в PowerShell - в отличие от оболочек типа POSIX, таких как Bash - нет необходимости заключать (строковые) переменные в "...", так какссылка на них как есть работает нормально, даже если они содержат встроенные пробелы;то есть, если $var является строкой, используйте ее как есть - нет необходимости в "$var".

0 голосов
/ 15 апреля 2019

Сделайте это следующим образом ...

$ Files = Get-Childitem -path \\ some \ path

Foreach ($ file in $ Files) {rename-item $ file.FullPath -NewName («что-то» + $ file.Name)

Это общая, но рабочая версия того, что вы хотите.Проблема в том, что вы на самом деле не получаете объекты, вы получаете список имен.

...