내가 지정한 파일에 대한 정보를 반환하는 "file"의 결과를 사용하려고 합니다.
예를 들어
file *.doc 'all .doc extensions
그런 다음 "생성 응용 프로그램 이름: Microsoft Word"를 포함하여 파일에 대한 정보를 반환합니다. 이제 "Word"라는 문자열에 대한 결과를 검색해 보겠습니다. 나는 여기에 갇혀있다. 실제로 어떻게 해야 합니까?
*몇시간의 검색 끝에 시도해본 내용입니다. 내가 찾고 있는 단어가 무엇인지 모르겠습니다. 조언해주세요.
find . -type f -print0 | xargs -0 grep -lh "Microsoft Word" | xargs -I % mv % ../NewDirectory/
나는 이것이 파일 자체에서 "Word"라는 문자열을 검색하여 새 디렉토리로 옮길 것이라고 생각했습니다.
답변1
내가 올바르게 이해했다면 파일을 현재 디렉터리와 그 하위 디렉터리에서 다른 디렉터리로 재귀적으로 이동하고 싶지만 명령이 해당 file
파일을 "Microsoft Word" 파일로 보고하는 경우에만 가능합니다. 즉, file "$filename" | grep 'Microsoft Word'
일부 출력을 생성하는 파일에 관심이 있습니다.
간단한 방법은 침착하게 일을 하나씩 처리하는 것입니다. 현재 디렉터리의 파일만 필요한 경우 for
루프와 와일드카드 패턴을 사용할 수 있습니다.
for f in *.doc; do
if …
done
조건은 무엇입니까? 출력 Microsoft Word
에 file "$f"
. 나는 file --
로 끝나는 이름을 방지 하곤 했습니다 -
.
for f in *.doc; do
if file -- "$f" | grep -s 'Microsoft Word'; then
…
fi
done
우리가 해야 할 일은 파일을 이동하는 명령을 추가하는 것뿐입니다.
for f in *.doc; do
if file -- "$f" | grep -s 'Microsoft Word'; then
mv -- "$f" ../NewDirectory/
fi
done
하위 디렉터리에서도 파일을 찾으려면 다음을 사용하세요.**
와일드카드 패턴재귀적 와일드카드에 사용됩니다. Bash에서는 활성화하려면 를 사용해야 합니다 shopt -s globstar
(ksh93에서는 을 수행 set -o globstar
하고 zsh에서는 즉시 작동합니다. 다른 셸에는 이 기능이 없습니다). bash 4.2 이하에서는 디렉터리에 대한 심볼릭 링크를 따릅니다.
for f in **/*.doc; do
if file -- "$f" | grep -s 'Microsoft Word'; then
mv -- "$f" ../NewDirectory/
fi
done
이동된 모든 파일은 ../NewDirectory/
생성된 하위 디렉터리 없이 끝난다는 점에 유의하세요. 디렉토리 트리를 재현하려면 다음을 사용할 수 있습니다.문자열 조작 구조파일 이름의 디렉터리 부분을 추출하고 mkdir -p
필요한 경우 대상 디렉터리를 만듭니다.
for f in ./**/*.doc; do
if file "$f" | grep -s 'Microsoft Word'; then
d="${f%/*}"
mkdir -p ../NewDirectory/"$d"
mv "$f" ../NewDirectory/"$d"
fi
done
file
다소 취약한 출력을 구문 분석하는 것보다 출력을 표준화된 문자열로 구문 분석하는 것을 선호할 수 있습니다 .file -i
답변2
첫 번째 예는 작은 따옴표가 일치하지 않기 때문에 작동하지 않지만 file
두 번째 예 때문에 그 점을 알아낸 것 같습니다.
이렇게 하면:
find . -type f
출력을 볼 수 있습니다. 파일 이름입니다. 해당 출력에서 무언가를 선택하려면 grep
다음을 사용하십시오 .
find . -type f | grep "Microsoft Word"
나열된 파일의 내용이 아닌 파일 이름으로 검색하십시오. 파일 이름에 개행 문자가 포함될 수 있고 "Microsoft Word"가 포함된 파일 이름에 이름의 일부로 개행 문자가 포함되어 있으면 출력이 불완전하기 때문에 이것은 완전히 정확하지는 않습니다.
이렇게 하면:
find . -type f -print0 | xargs -0 grep -lh "Microsoft Word"
이 xargs
부분은 실제로 파일 이름을 grep에 전달합니다( -print0
for find
및 -0
for는 xargs
개행 문자가 있는 파일 이름을 처리합니다). 그러면 "Word"뿐만 아니라 "Microsoft Word" 전체 문자열이 검색됩니다.파일에.
지정된 -lh
for는 grep
파일 이름을 나열하며 파일 이름의 줄 바꿈이 정상적으로 인쇄되기 때문에 문제가 있을 수 있으므로 -Z를 지정하여 NUL로 끝나는 파일 이름을 계속 사용해야 합니다. 지정하지 않으면 -l
행 일치도 수행되므로 추가 처리가 mv
불가능해집니다.
모든 파일을 하나의 디렉토리로 이동하려는 경우 일반적으로 ' 옵션( 입력에서 읽은 인수를 기본 줄 끝과 다른 위치에 넣을 수 있지만 속도가 느림) mv -t
대신 사용하는 것이 더 쉽습니다. mv는 파일당 한 번씩 호출됩니다.)xargs
-I
xargs
find . -type f -print0 | xargs -0 grep -lhZ "Microsoft Word" | xargs -0 mv -t ../NewDirectory/
이렇게 하면 모든 파일이 "Microsoft Word"가 포함된 현재 디렉터리 아래의 위치로 이동됩니다.콘텐츠NewDirectory
현재 디렉토리 옆에 . 반드시 존재해야 한다는 점에 유의하세요 ../NewDirectory
.