Eu tenho alguns arquivos em um diretório que contém a string "HG-U133A" ou "HG-U133B". Eu gostaria de escrever um script que possa percorrer todos os arquivos do diretório e renomear todos os arquivos "HG-U133A" com o prefixo "A_" e todos os arquivos "HG-U133B" com o prefixo "B_".
Então, se esses são os arquivos do meu diretório
> grep "HG-U133[AB]" *
fileA.txt: HG-U133A
fileB.txt: HG-U133A
fileC.txt: HG-U133B
fileD.txt: HG-U133A
fileE.txt: HG-U133B
Eu gostaria de escrever um script que pudesse renomear esses arquivos para
> ls
A_fileA.txt
A_fileB.txt
B_fileC.txt
A_fileD.txt
B_fileE.txt
Eu realmente aprecio alguma ajuda com isso. Obrigado
Responder1
Esta é uma solução portátil que não se enquadra noArmadilha do Bash número 1.
for file in *; do
[ -f "$file" ] || continue
grep -q -- HG-U133A "$file" && { mv -- "$file" "A_$file"; continue; }
grep -q -- HG-U133B "$file" && mv -- "$file" "B_$file"
done
Notas:
*
não corresponde a dotfiles, mas você o usou em suagrep
invocação, então presumo que o comportamento seja adequado para você ou que você saiba como alterá-lo.*
corresponde aos diretórios. Seugrep
foi invocado sem opções que possam fazer com que ele processe diretórios. O script pula qualquer coisa que não seja um arquivo normal e o objetivo principal disso é pular diretórios e não se preocupar em executágrep
-los (o que falharia de qualquer maneira).- O traço duplo (
--
) é explicado aqui:O que significa--
(traço duplo)? (também conhecido como “traço duplo nu”)?É o caso de algum dos nomes de arquivos começar com um travessão. Se usássemos./*
em vez de,*
não precisaríamos dele. - Você disse "ou… ou…", eu interpreto isso como "para um determinado arquivo, no máximo uma string corresponderá". Portanto,
continue
depois do primeirogrep
. Está aí para não chamar o segundogrep
em vão. - Se você espera muitos arquivos
HG-U133B
e apenas poucosHG-U133A
, considere testarHG-U133B
primeiro.
Vantagens:
- portabilidade,
- robustez (o código deve funcionar bem independentemente dos nomes dos arquivos).
Desvantagem:
- gerar pelo menos um
grep
processo por arquivo regular está longe de ser ideal; isso pode tornar as coisas mais lentas se houver mais do que poucos arquivos para inspecionar.
Responder2
Os seguintes comandos bash
farão isso:
for file in `grep -l HG-U133A *` ; do mv "$file" "A_$file" ; done
for file in `grep -l HG-U133B *` ; do mv "$file" "B_$file" ; done