
Estou tentando pesquisar recursivamente em uma lista de arquivos e, se o arquivo contiver uma string, renomeie o arquivo para os resultados do grep dessa string.
Os arquivos de amostra contêm o seguinte conteúdo:
file1
foo bar1
file2
foo bar2
file3
foo bar3
file4
foo bar4
file5
foo bar5
grep + awk retorna os resultados que preciso:
$ grep -r "^foo" . | awk '{print $2}'
bar1
bar2
bar3
bar4
bar5
Não consigo passar esses resultados para um comando mv.
$ grep -r "^foo" . | awk '{print $2}' | xargs -I{} mv {} .
mv: cannot stat 'bar1': No such file or directory
mv: cannot stat 'bar2': No such file or directory
mv: cannot stat 'bar3': No such file or directory
mv: cannot stat 'bar4': No such file or directory
mv: cannot stat 'bar5': No such file or directory
Desde já, obrigado. Gnu/BSD Grep têm os mesmos resultados.
Responder1
Eu usaria um loop for shell:
for match in "$(grep -ro '^foo.*')";do
echo mv "${match%:*}" "${match#*:}"
done
Isso irá iterar todas as correspondências file:matching-substring
e usar os operadores de string %
e #
para excluir tudo, respectivamente. tudo depois, e inclusive :
.
Observe que se você realmente deseja corresponder a linha inteira em vez de apenas a substring que corresponde ao padrão, use
for match in $(grep -r '^foo');do
Certifique-se de colocar aspas duplas, pois as correspondências e/ou nomes de arquivos podem conter espaços.
Se você deseja fazer a correspondência por um padrão, mas renomear o arquivo para a segunda palavra na linha correspondente:
for match in "$(grep -ro '^foo.*')";do
fname=$("echo ${match#*:}|awk '{print $2}'")
echo mv "${match%:*}" "$fname"
done
Responder2
Você pode fazer o que está tentando realizar usando perl:
#!/usr/bin/env perl
use strict;
my $dir = "/path/to/directory";
chdir $dir or die "Cannot open $dir!";
my @files = grep { -f } glob("*");
foreach my $file(@files) {
open F1, "<", $file or die "Cannot open file $file! $!\n";
while ( <F1> ){
chomp;
my @strings = split(' ');
if($strings[1] =~ /bar/){
system("/bin/mv $file $strings[1]");
}
}
close(F1);
}
Responder3
find . -type f -exec egrep -il '^foo' {} \; | sort | while IFS='' read -r line; do mv -n "$line" "$(dirname "$line")"'/'"$(egrep -i '^foo' "$line" | awk '{ print $2 }')"; done