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
인라인 스크립트에 대해 쉘 옵션이 설정되어 구성된 패턴이 다음을 수행하는지 확인합니다 .~ 아니다일치하는 항목이 있으면 패턴이 제거됩니다(확장되지 않은 상태로 유지되는 대신).
귀하의 예제에 표시된 파일 이름과 일치하지 않는 문자열이 있기 때문에 패턴이 일치하는지 명시적으로 테스트하고 있습니다. 이는 위치 매개변수 목록을 glob 확장 결과로 설정한 다음 목록의 길이( $#
)가 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
또는 이름이 a로 시작 -
하거나 다른 이상한 문자가 포함될 수 있는 경우 다음을 사용하세요.
$ 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=""