重命名文件名

lok*_*oki -1 awk split

当前目录下存在以下文件

 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
Run Code Online (Sandbox Code Playgroud)

我想像这样重命名当前文件

 GCF_000901975.1
 GCF_001885505.1
 GCF_000901995.1
 GCF_001041015.1
Run Code Online (Sandbox Code Playgroud)

我正在使用下面的脚本来获取它,但它失败了

 for file in `ls | grep .gz`
 do
    newfile=`echo $file | awk -F "_" '{print $1,"_",$2,".gz"| sed 's/ //g"`
    mv $file $newfile
 done
Run Code Online (Sandbox Code Playgroud)

有人可以给我一些建议吗?或者也许我应该尝试“拆分”,欣赏它

ter*_*don 7

首先,避免解析ls. 接下来,即使您有充分的理由解析ls输出(这里没有),也没有理由传递它grepls *gz将仅列出以 结尾的文件和目录名称gz(但请注意,它还会列出名称以 结尾的目录的内容,gz除非您使用ls -d) 和,不像ls | grep .gz不会匹配像 , 之类的文件not.a.gz.file,并且会匹配名称中带有换行符的文件。

\n

ls无论如何,您在这里根本不需要或想要,您想要for file in *gz的只是这是一种更好的方法,因为它可以处理任意文件名(只要您正确引用变量)。

\n

因此,您的循环可以更好地写为:

\n
for file in *.gz; do\n    newfile=$(echo "$file" | awk -F "_" \'{print $1"_"$2".gz"}\' | sed \'s/ //g\')\n    mv -- "$file" "$newfile"\n done\n
Run Code Online (Sandbox Code Playgroud)\n

awk请注意我如何修复您的 awk 和 sed 命令,因为您在打开该部件之前没有关闭该sed部件以及如何引用所有变量。另请注意我如何删除,awkprint语句中的 ,因为它们会OFS在每个打印项目之间添加空格(或您设置变量的任何内容)。用于-- 指示命令行选项的结尾,并确保该命令适用于以-.

\n

接下来,您实际上不需要awk或根本不需要sed。您可以使用外壳:

\n
for f in *gz; do \n    echo mv -- "$f" "${f%%_V*}"\ndone\n
Run Code Online (Sandbox Code Playgroud)\n

语法${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阅读有关它的更多信息:

\n
\n

${参数%%字}

\n

该单词被扩展以产生模式并根据下面描述的规则进行匹配(请参阅模式匹配)。如果模式与参数扩展值的尾部部分匹配,则扩展的结果是具有最短匹配模式(\xe2\x80\x98%\xe2\x80\x99 情况)或最长匹配模式的参数值匹配模式(\xe2\x80\x98%%\xe2\x80\x99 情况)已删除。如果参数为 \xe2\x80\x98@\xe2\x80\x99 或 \xe2\x80\x98 \xe2\x80\x99,则模式删除操作依次应用于每个位置参数,扩展为结果列表。如果参数是下标为 \xe2\x80\x98@\xe2\x80\x99 或 \xe2\x80\x98 \xe2\x80\x99 的数组变量,则模式删除操作将依次应用于数组的每个成员,展开就是结果列表。

\n
\n

一旦您对它按预期工作感到满意,请删除echo并再次运行它以实际重命名文件。

\n

最后,如果你有 perl-rename (称为rename在基于 Debian 的 Linux 发行版上调用),您还可以执行以下操作:

\n
$ rename -n -- \'s/_V.*//s\' *gz\nGCF_000901975.1_ViralProj181986_genomic.fna.gz -> GCF_000901975.1\nGCF_000901995.1_ViralProj181990_genomic.fna.gz -> GCF_000901995.1\nGCF_001041015.1_ViralProj287961_genomic.fna.gz -> GCF_001041015.1\nGCF_001885505.1_ViralProj344311_genomic.fna.gz -> GCF_001885505.1\n
Run Code Online (Sandbox Code Playgroud)\n

如果看起来没问题,请删除-n来实际重命名文件。

\n