Могу ли я обновить прошивку с помощью виртуальной машины?

1

Для вашего первого шага в вашем примере команды вам не нужен * , потому что он не фильтрует ни один файл. Что вам действительно нужно, так это отфильтровать .git , как это:

$ find . -name '.git' -prune -o -type f -print

Это отклонит ( -prune ) любой каталог с точным именем .git и все, что внутри Это.

Это устраняет необходимость grep -v ".git" . Нельзя было избежать sed, поскольку он редактирует внутреннюю часть файла, а не то, что может сделать find.

Но все же мы можем упростить (цитируя точку внутри sed):

$ find . -name '.git' -prune -o -type f -exec sed -i 's/com\.foo/org\.bar/g' '{}' \+

Это накапливает имена файлов (аналогично xargs) в команде sed .

Но даже лучше:

$ find . -name '.git' -prune -o -type f -execdir sed -i 's/com\.foo/org\.bar/g' '{}' \+

Которая будет выполнять по одному экземпляру sed для каждого каталога.

2 и 3

Давайте определим функцию для выполнения переименования каталога:

$ renamedir (){ find "$1" -name '.git' -prune -o -type d -exec bash -c 'mv "$1" "${1//"$2"/$3}"' sh '{}' "$2" "$3" \; ; }

Шаг 2:

  • для всех каталогов (кроме .git) в src / com переименовать в src / org

     $ renamedir 'd / src / com' src / com 'src / org' 
     

Шаг 3:

  • для всех каталогов (кроме .git) в src / org / foo переименовать в src / org / bar

     $ renamedir 'src / org / foo' 'ogr / foo' 'org / bar' 
     

4

Шаг 4:

  • для всех имен файлов и каталогов ( исключая .git) с com.foo в имени, измените эту часть на org.bar.

     $ find. -name '.git' -prune -o -name "com.foo" -type f -exec bash -c 'mv "$ 1" "$ {1 //" $ 2 "/ $ 3}"' sh '{}' " com.foo "" org.bar "\; ; } 
     

Все внутри (лучше отформатированного) сценария:

#!/bin/bash

# NOTE: There are three echo to avoid execution of commands.
#       If after testing, you decide that it is ok to execute commands,
#       remove the echo words.

# Step 1:
### for all files (excluding .git) in . change
###     file contents from com.foo to org.bar
find . -name '.git' -prune -o -type f -execdir echo sed -i 's/com\.foo/org\.bar/g' '{}' \+

renamedir (){ find "$1" -name '.git' -prune -o -type d -exec bash -c '
                  echo \
                  mv "$1" "${1//"$2"/$3}"
              ' sh '{}' "$2" "$3" \;
        }

# Step 2:
### for all directories (excluding .git) in src/com rename to src/org
renamedir 'd/src/com' 'src/com' 'src/org'

# Step 3:
### for all directories (excluding .git) in src/org/foo rename to src/org/bar
renamedir 'src/org/foo' 'org/foo' 'org/bar'

# Step 4:
### for all file and directory names (excluding .git)
### with "com.foo" in the name, change that portion to "org.bar".
find . -name '.git' -prune -o -name "*com.foo*" -type f -exec bash -c '
    echo \
    mv "$1" "${1//"$2"/$3}"
' sh '{}' "com.foo" "org.bar" \; ; }

Чтобы проверить различные версии сопоставления, создайте целое дерево файлов, как это (удалите его позже с помощью rm -rf./ d / ):

$ mkdir -p d/src/{{,.git}{,one},com/{{,.git}{,two},\ .git,.git/six},org/{{,.git}{,three},bar/{,.git}{,four},foo/{,.git}{,five}}}
$ touch d/src/{111,com/{222,.git/666},org/{333,bar/444,foo/555}}  
$ touch d/src/{.git/{aaa,one/aaaaa},one/aaa111,com/.git{/bbb,two/bbb222},org/{.git{/ccc,three/ccc333},bar/.git{/ddd,four/ddd444},foo/.git{/eee,five/eee555}}}               

Ваша исходная команда (с использованием параметра GNU -z для сопоставления find -print0) будет соответствовать (в этом каталоге):

$ find d/ -type f -print0 | grep -zZv \.git
find d/ -type f -print0 | grep -zZv \.git | xargs -0 printf '<%s>\n'
<d/src/org/333>
<d/src/org/foo/555>
<d/src/org/bar/444>
<d/src/com/222>
<d/src/111>

Только пять файлов, которые не имеют отношения ни к чему .git .


В общем:

Есть три основных способа сопоставить .git в find : -name , -regex и -path . Оставляя в стороне -regex , который помимо нечетного (использует регулярное выражение emacs), необходим только для сложных совпадений, которые здесь не нужны.

find d / -path "./.git" будет соответствовать именно этому: только внутреннему каталогу .git .
Или (для созданного каталога) найти. -path './d/src/.git' будет соответствовать только ./ d / src / .git

A find d / -name ".git" будет соответствовать ровно .git на последнем уровне (базовом имени) дерева.

И -name "* .git" , и -path "* .git" будут совпадать.
Любая строка, которая заканчивается на .git .

Что начинает усложняться, так это когда мы добавляем две звездочки: *. Git *
В этом случае -name будет соответствовать только на последнем уровне пути (базовое имя файла), но из-за наличия двух звездочек * также будет соответствовать именам с префиксом (обратите внимание на пробел в .git ) и постфиксом (обратите внимание на многие, такие как .gitone ):

$ find d -name '*.git*'
d/src/org/.gitthree
d/src/org/foo/.git
d/src/org/foo/.gitfive
d/src/org/bar/.gitfour
d/src/org/bar/.git
d/src/org/.git
d/src/com/.gittwo
d/src/com/.git
d/src/com/ .git
d/src/.git
d/src/.gitone

будет соответствовать .git на любом уровне пути, почти как grep.Не совсем то же самое, что grep, поскольку grep может иметь сложное Regex, но здесь совпадение противоречит простому «шаблону». Обратите внимание на d / src / com / .git / six ниже:

$ find d -path '*.git*'
d/src/org/.gitthree
d/src/org/foo/.git
d/src/org/foo/.gitfive
d/src/org/bar/.gitfour
d/src/org/bar/.git
d/src/org/.git
d/src/com/.gittwo
d/src/com/.git
d/src/com/.git/six
d/src/com/ .git
d/src/.git
d/src/.gitone

Затем мы можем изменить такие совпадения несколькими способами, используя ( не или ! ), который отклонит то, что соответствует следующему:

Не (!)

Если найти d -name '.git' будет соответствовать:

d/src/org/foo/.git
d/src/org/bar/.git
d/src/org/.git
d/src/com/.git
d/src/.git

Тогда найти d -not -name '.git' (или, точный эквивалент: find d! -name '.git' ) будет соответствовать всем остальным. Здесь не печатается, поскольку список довольно долго.

Но выбор только файлов короткий (обратите внимание на файл 666 ):

$ find d -not -name '.git' -type f
d/src/org/333
d/src/org/foo/555
d/src/org/bar/444
d/src/com/222
d/src/com/.git/666
d/src/111

И -path в find d -not -path '* .git *' -type f будет соответствовать только пяти файлам:

$ find d -not -path '*.git*' -type f
d/src/org/333
d/src/org/foo/555
d/src/org/bar/444
d/src/com/222
d/src/111

Prune

Или мы можем использовать -prune , чтобы «вырезать» или «удалить» все каталоги, которые соответствуют предыдущему принято:

$ find d \( -name '.git' -prune \) -o \( -print \)
d
d/src
d/src/org
d/src/org/three
d/src/org/333
d/src/org/.gitthree
d/src/org/foo
d/src/org/foo/five
d/src/org/foo/555
d/src/org/foo/.gitfive
d/src/org/bar
d/src/org/bar/.gitfour
d/src/org/bar/four
d/src/org/bar/444
d/src/one
d/src/com
d/src/com/.gittwo
d/src/com/222
d/src/com/two
d/src/com/ .git
d/src/111
d/src/.gitone

Должно быть что-то после -prune. Обычно "-o", а здесь также -print , чтобы соответствовать всему, что обрезка не соответствует. Как видите, это совпадение намного больше, чем пять файлов вашей команды. Замена '. Git' на '*. Git' удалит только ] d / src / com / .git . Но использование '*. git *' будет работать ближе к grep (все еще не совсем то же самое):

$ find d \( -name '*.git*' -prune \) -o \( -print \)
d
d/src
d/src/org
d/src/org/three
d/src/org/333
d/src/org/foo
d/src/org/foo/five
d/src/org/foo/555
d/src/org/bar
d/src/org/bar/four
d/src/org/bar/444
d/src/one
d/src/com
d/src/com/222
d/src/com/two
d/src/111

Это будет соответствовать только пяти файлам (не каталогам) вашей команды:

$ find d \( -name '*.git*' -prune \) -o \( -type f -print \)

Также это будет соответствовать только первым пяти файлам.Добавление -типа f скрывает множество деталей:

$  find d \( -name '.git' -prune \) -o \( -type f -print \)

Обычно без скобок (менее ясно):

$ find d -name '.git' -prune -o -type f -print

Предупреждение: удаление -print может иметь непредвиденные побочные эффекты.

4
22.12.2016, 10:02
1 ответ

Я уверен, что у кого-то другого будет лучший и более информированный ответ, но вот мои два цента в любом случае:

Это, вероятно, будет хорошо.

Приложения для обновления прошивки - при запуске на Windows или macOS - скорее всего, просто отправляют определенные USB-сообщения на устройство.

Я ожидаю, что ваша виртуальная машина либо полностью пропустит эти сообщения, либо вообще откажется их передавать.

Я сомневаюсь, что существует большой риск "окирпичивания" вашего устройства таким образом, поскольку я ожидаю, что USB-сообщения будут отправляться полностью или не будут отправляться вообще.

Если вы не желаете рисковать, выходя за рамки политики поддержки производителя, вам придется обратиться к ним с вопросом о возможных вариантах. (Скорее всего, они посоветуют вам найти машину с Windows или macOS)

.
1
27.01.2020, 21:01

Теги

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