파일 목록을 재귀적으로 검색하려고 하는데, 파일에 문자열이 포함되어 있으면 파일 이름을 해당 문자열의 grep 결과로 바꿉니다.
샘플 파일에는 다음 콘텐츠가 포함되어 있습니다.
file1
foo bar1
file2
foo bar2
file3
foo bar3
file4
foo bar4
file5
foo bar5
grep + awk는 필요한 결과를 반환합니다.
$ grep -r "^foo" . | awk '{print $2}'
bar1
bar2
bar3
bar4
bar5
나는 이 결과를 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
미리 감사드립니다. Gnu/BSD Grep의 결과는 동일합니다.
답변1
루프용 쉘을 사용하겠습니다.
for match in "$(grep -ro '^foo.*')";do
echo mv "${match%:*}" "${match#*:}"
done
그러면 모든 일치 항목을 반복하고 file:matching-substring
및 %
문자열 연산자를 사용하여 #
모든 항목을 제거합니다 . .:
패턴의 하위 문자열이 아닌 전체 행을 일치시키려면 다음을 사용하십시오.
for match in $(grep -r '^foo');do
일치 항목 및/또는 파일 이름에 공백이 포함될 수 있으므로 큰따옴표를 사용하십시오.
패턴으로 일치시키고 싶지만 줄의 두 번째 단어와 일치하도록 파일 이름을 바꾸는 경우:
for match in "$(grep -ro '^foo.*')";do
fname=$("echo ${match#*:}|awk '{print $2}'")
echo mv "${match%:*}" "$fname"
done
답변2
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);
}
답변3
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