当前目录下存在以下文件
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
_ which comes before a
V`。您可以阅读更多相关信息这里:
${参数%%字}
该单词被扩展以产生模式并根据下面描述的规则进行匹配(请参阅模式匹配)。如果模式与参数扩展值的尾部部分匹配,则扩展的结果是具有最短匹配模式(“%”情况)或最长匹配模式(“%%”情况)的参数值已删除。如果参数是“@”或“',模式移除操作依次应用于每个位置参数,扩展是结果列表。如果参数是一个数组变量,下标为“@”或“',模式删除操作依次应用于数组的每个成员,扩展是结果列表。
一旦您对它按预期工作感到满意,请删除echo
并再次运行它以实际重命名文件。
最后,如果您有 perl-rename (rename
在基于 Debian 的 Linux 发行版上调用),您还可以执行以下操作:
$ 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