strings.txt
문자열 목록이 포함된 파일이 있습니다.
GCA_001677475.1
GCA_003410275.1
GCA_002310615.1
GCA_000007405.1
GCA_000219515.3
내 디렉토리에 다음 이름을 가진 파일이 많이 있습니다.
GCA_000005845.2_ASM584v2_protein.faa
GCA_000006925.2_ASM692v2_protein.faa
GCA_000007405.1_ASM740v1_protein.faa
GCA_000007445.1_ASM744v1_protein.faa
GCA_000008865.2_ASM886v2_protein.faa
GCA_000009565.2_ASM956v1_protein.faa
그 이름을 로 옮기면 됩니다 . 지금까지 다음 과 같이 strings.txt
사용해 보았습니다 .xargs
mv
cat strings.txt | xargs -I % mv %*faa ./Data
그러나 그것을 정규식으로 취급 mv
하지 않고 %*faa
정확한 이름을 가진 파일을 찾으려고 시도합니다(물론 아무것도 찾지 못합니다). 나는 또한 사용해 보았지만 ls
같은 방식으로 작동합니다.
cat strings.txt | xargs -I {} ls {}*faa
그럼 어떻게 해야 하나요?
답변1
xargs bash -O nullglob -c '
for prefix do
set -- "$prefix"*.faa
[ "$#" -gt 0 ] && mv -- "$@" ./Data
done' sh <strings.txt
이는 인라인 스크립트 에 xargs
일괄적으로 문자열을 공급하는 데 사용됩니다 .strings.txt
bash
각 문자열에 대해 인라인 스크립트는 현재 디렉터리에 해당 문자열( 패턴을 만들기 위해 끝에 bash
추가됨)과 일치하는 파일 이름이 있는지 여부를 테스트하고 , 그렇다면 해당 파일이 이미 존재한다고 가정하여 해당 디렉터리로 이동합니다.*.faa
Data
인라인 스크립트에 대한 셸 옵션을 설정하여 nullglob
구성된 패턴이아니요무엇이든 일치하면 패턴이 제거됩니다(확장되지 않은 채로 남아 있는 것이 아님).
귀하의 예에 있는 일부 문자열이 귀하가 표시한 파일 이름과 일치하지 않기 때문에 패턴 일치를 명시적으로 테스트하고 있습니다. 이는 위치 인수 목록을 전역 확장 결과로 설정한 다음 목록의 길이( )가 0보다 큰지 테스트하여 $#
수행 됩니다.
분명히 다음과 같이 대신 이 작업을 수행할 수도 있습니다 xargs
.
shopt -s nullglob
while IFS= read -r prefix; do
set -- "$prefix"*.faa
[ "$#" -gt 0 ] && mv -- "$@" ./Data
done <strings.txt
이것은 여전히실패하다접두사 문자열 중 하나가 수천 개의 파일 이름과 일치하는 경우( mv
명령줄이 너무 길어집니다). 이 경우에는 다음을 사용할 수 있습니다.
shopt -s nullglob
while IFS= read -r prefix; do
set -- "$prefix"*.faa
if [ "$#" -gt 0 ]; then
printf '%s\n' "$@" | xargs sh -c 'mv -- "$@" ./Data' sh
fi
done <strings.txt
이는 접두사 문자열이나 파일 이름에 개행 문자가 포함되어 있지 않다고 가정합니다.
답변2
가능한 해결책은 다음과 같습니다.
cat strings.txt | xargs -I '%' find . -type f -name "%*" -exec mv -t your_path {} +
터치한 GCA_000007405.1_ASM740v1_protein.faa
것이 유일한 일치 항목입니다.
답변3
필요도 없고 xargs
복잡한 것도 없습니다. 모든 파일이 동일한 디렉터리에 있는 경우 다음을 수행하면 충분합니다.
$ while read string; do
mv "$string"_* ./Data;
done < strings.txt
또는 이름이 로 시작 -
하거나 다른 이상한 문자가 포함된 경우 다음을 사용하세요.
$ while read -r string; do
mv -- "$string"_* ./Data;
done < strings.txt
답변4
빠르고 더러운 해킹:cat strings.txt| xargs -i sh -c 'mv {}* your/path/'>&/dev/null
더 적은 수의 올바른 해킹:export dir=$(ls -1); cat strings.txt| xargs -i sh -c 'grep "^{}" <<<$dir && mv {}* your/path'; dir=""