현재 디렉터리에 다음 파일이 있습니다.
GCF_000901975.1_ViralProj181986_genomic.fna.gz
GCF_001885505.1_ViralProj344311_genomic.fna.gz
GCF_000901995.1_ViralProj181990_genomic.fna.gz
GCF_001041015.1_ViralProj287961_genomic.fna.gz
현재 파일의 이름을 이렇게 바꾸고 싶습니다
GCF_000901975.1
GCF_001885505.1
GCF_000901995.1
GCF_001041015.1
아래 스크립트를 사용하여 가져오지만 실패합니다.
for file in `ls | grep .gz`
do
newfile=`echo $file | awk -F "_" '{print $1,"_",$2,".gz"| sed 's/ //g"`
mv $file $newfile
done
누구든지 나에게 조언을 해줄 수 있습니까? 아니면 "분할"을 시도하고 감사해야 할 수도 있습니다.
답변1
첫 번째,출력 구문 분석 방지ls
. 다음으로, ls
출력을 구문 분석해야 하는 타당한 이유(여기에는 없음)가 있더라도 이를 전달할 이유가 없습니다 grep
. ls *gz
로 끝나는 파일 및 디렉터리 이름만 나열됩니다 gz
(그러나 디렉터리도 나열된다는 점에 유의하세요). 로 끝나는 콘텐츠 이름과 달리 ) 및 를 gz
사용하지 않는 한 와 같은 파일은 일치하지 않으며 이름에 개행 문자가 있는 파일과 일치합니다.ls -d
ls | grep .gz
not.a.gz.file
어쨌든 ls
여기서는 전혀 필요하지도 원하지도 않습니다. 원하는 것은 for file in *gz
임의의 파일 이름을 처리할 수 있기 때문에 이것이 더 나은 접근 방식이라는 것입니다(변수를 올바르게 인용하는 한).
따라서 루프는 다음과 같이 더 잘 작성할 수 있습니다.
for file in *.gz; do
newfile=$(echo "$file" | awk -F "_" '{print $1"_"$2".gz"}' | sed 's/ //g')
mv -- "$file" "$newfile"
done
awk
부품을 열기 전에 닫지 않았기 때문에 awk 및 sed 명령을 수정한 방법 sed
과 모든 변수를 어떻게 인용했는지 확인하세요. 또한 인쇄된 각 항목 (또는 변수에 설정한 항목) ,
사이에 공백을 추가할 때 awk 문을 어떻게 제거했는지 확인하세요 . 이것print
OFS
--
명령줄 옵션의 끝을 나타내는 데 사용됩니다.그리고 명령이 -
.
다음으로, 정말로 필요하지 않거나 awk
전혀 sed
필요하지 않습니다. 쉘을 사용할 수 있습니다.
for f in *gz; do
echo mv -- "$f" "${f%%_V*}"
done
구문 ${variable%%pattern}
( "${f%%_V*}") means "return the value of $variable after removing the longest string matching $pattern from the end". So, in this case, it means "remove everything from the first
_V` which comes before a
. 이에 대한 자세한 내용을 읽을 수 있습니다.여기:
${매개변수%%단어}
단어가 확장되어 패턴을 생성하고 아래 설명된 규칙에 따라 일치됩니다(패턴 일치 참조). 패턴이 매개변수 확장 값의 후행 부분과 일치하는 경우 확장 결과는 가장 짧은 일치 패턴("%" 케이스) 또는 가장 긴 일치 패턴("%%" 케이스)이 있는 매개변수 값이 제거됩니다. 매개변수가 "@" 또는 "인 경우'를 사용하면 각 위치 인수에 패턴 제거 작업이 차례로 적용되고 확장이 결과 목록이 됩니다. 매개 변수가 배열 변수인 경우 아래 첨자는 "@" 또는 "' 패턴 제거 작업이 배열의 각 구성원에 차례로 적용되고 확장이 결과 목록입니다.
예상대로 작동하는 것에 만족하면 삭제 echo
하고 다시 실행하여 실제로 파일 이름을 바꿉니다.
마지막으로 perl-rename(Debian 기반 Linux 배포판에서 호출됨)이 있는 경우 rename
다음을 수행할 수도 있습니다.
$ rename -n -- 's/_V.*//s' *gz
GCF_000901975.1_ViralProj181986_genomic.fna.gz -> GCF_000901975.1
GCF_000901995.1_ViralProj181990_genomic.fna.gz -> GCF_000901995.1
GCF_001041015.1_ViralProj287961_genomic.fna.gz -> GCF_001041015.1
GCF_001885505.1_ViralProj344311_genomic.fna.gz -> GCF_001885505.1
괜찮아 보이면 삭제 -n
하여 실제로 파일 이름을 바꾸세요.
답변2
for i in $(ls GCF*.gz); do var=$(echo $i | awk -F "_" '{print $1"_"$2}'); echo $var; mv $i $var; done
awk 메서드
ls -ltr | awk '/GCF.*gz/{print "mv "$NF" "substr($NF,1,15)}'|sh