한 디렉토리에 그런 파일이 몇 개 있습니다
00.01.02 0000 some filename 1.pdf
00.01.02 0000 some filename 1.txt
02.03.07 0163 another filename 2.pdf
02.03.07 0163 another filename 2.txt
특정 문자열이 포함된 모든 txt 파일을 찾은 다음 이 txt 파일과 해당 pdf 파일을 다른 디렉터리로 이동해야 합니다.
이 작업을 수행하는 가장 좋은 방법은 무엇입니까?
답변1
3가지 옵션이 있습니다. 기본 아이디어는 다음과 같습니다.
grep | xargs mv
grep | parallel mv
find -exec grep -q -exec mv
1.grep | xargs mv
사용 grep
및 xargs
:
grep -FlZ "some string" *.txt \
| xargs -0 -I{} sh -c 'echo mv "$1" "${1%.*}.pdf" some/other/directory' xargs-sh {}
grep
:
-F
패턴이 아닌 전체 문자열과 일치-l
일치하는 파일 이름만 출력-Z
파일 이름 사이에 0 구분 기호를 출력합니다. (파일 이름에 개행 문자가 허용되어 개행 문자를 구분 기호로 사용할 수 없기 때문에 이는 중요합니다.)
xargs
:
-0
0으로 구분된 데이터를 읽습니다.
2.grep | parallel mv
해당 PDF 파일 이름을 얻으려면 를 xargs
사용하여 서브셸을 호출해야 합니다 .sh -c
그 대신에 멋진 기능을 활용할 수도 있습니다 GNU parallel
!!
grep -FlZ "some string" *.txt \
| parallel -0 -j1 echo mv {} {.}.pdf some/other/directory
-j1
한 번에 하나의 직업만{}
파일 이름{.}
확장자가 없는 파일 이름
삼.find -exec grep -q -exec mv
그리고 또 다른 대안은 다음을 사용하는 것 find
입니다.
find . -maxdepth 1 -name "*.txt" \
-exec grep -Fq "some string" {} \; \
-exec sh -c 'echo mv "$1" "${1%.*}.pdf" some/other/location' find-sh {} \;
-maxdepth 1
재발하지 않도록grep -q
파일 이름 대신 오류 코드만 얻으려면 두 번째는-exec
첫 번째가 성공한 경우에만 실행됩니다.- 두 번째는 기본적으로 첫 번째 옵션
-exec
과 동일합니다 .xargs
- 파일 이름을 전달하지 않고 처리하므로 0으로 구분된 출력 작업을 수행할 필요가 없습니다
find
.
각 옵션에 대해 echo
출력이 만족스러우면 제거하세요.
답변2
문제를 여러 조각으로 나누세요.
"현재 디렉터리에서 주어진 문자열을 포함하는 모든 텍스트 파일을 찾아야 합니다."
grep -F "text string just as written (no regex)" *.txt
"나는 ~을 원한다파일 이름그 파일들 중"
grep -l -F "text string" *.txt
"각 파일에 대해..."
for...each는 while/do/done
파일 목록을 전달할 구성을 사용하여 수행합니다. 실행할 수 있는 각 파일에 대해무엇, 변수에 액세스할 수 있습니다 $file
.
grep -l -F "text string" *.txt \
| while IFS= read -r file ; do
...something...
done
"뭔가"는
"...txt 파일과 해당 pdf 파일을 이동합니다..."
따라서 ".txt"가 없는 기본 이름이 필요합니다.
BASE=$( basename ${file} .txt )
그리고 마지막으로 모든 것을 종합하면 다음과 같습니다.
grep -l -F "text string" *.txt \
| while IFS= read -r file ; do \
BASE=$( basename ${file} .txt )
mv ${BASE}.txt /some/other/dir
mv ${BASE}.pdf /some/other/dir
done
(참고로 이는 각파일그렇지 않으면 경로가 제거되므로 경로가 없습니다 basename
.)
답변3
command 가 없으면 아래와 같이 parallel
두 가지로 수행하십시오.xargs
grep -l 'search string' *.txt | xargs -I {} basename {} .txt | xargs -I {} cp {}.pdf /destination-directory