파일에서 문자열을 검색하고 여러 파일의 이름을 결과로 바꿉니다.

파일에서 문자열을 검색하고 여러 파일의 이름을 결과로 바꿉니다.

파일 목록을 통해 재귀적으로 검색을 시도하고 있으며 파일에 문자열이 포함되어 있으면 파일 이름을 해당 문자열의 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-loop를 사용하겠습니다.

for match in "$(grep -ro '^foo.*')";do
    echo mv "${match%:*}" "${match#*:}"
done

그러면 모든 일치 항목이 반복 file:matching-substring되고 %# resp까지 모든 항목을 삭제합니다. .:

패턴과 일치하는 하위 문자열만 일치시키는 것이 아니라 전체 행을 일치시키려면 다음을 사용하십시오.

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

관련 정보