简体   繁体   English

删除bash中的中间名

[英]Remove middle of name in bash

I have 300+ files named:我有 300 多个文件名为:

T1_0000106_FS1_MAX_5743.nii.gz  T1_0000214_FS1_MAX_5475.nii.gz
T1_0000107_FS1_MAX_5477.nii.gz  T1_0000215_FS1_MAX_6162.nii.gz

I would like to remove everything between T1 and _5/6*.nii.gz so:我想删除 T1 和 _5/6*.nii.gz 之间的所有内容,因此:

T1_5743.nii.gz  T1_5475.nii.gz
T1_5477.nii.gz  T1_6162.nii.gz 

I can't figure out why it isn't working;我不知道为什么它不起作用; I tried (from another post):我尝试过(来自另一篇文章):

 for file in *.gz;
 do new_name=$(sed 's/_[^.]*_/_g' <<< "new_name");
 mv "$file" "$new_name"; done

and variations of rename/sed but nothing changes.和 rename/sed 的变体,但没有任何变化。

Problems with your script include, at least,你的脚本问题至少包括,

  • s/_[^.]*_/_g is not a valid sed command. s/_[^.]*_/_g不是有效的sed命令。 You appear to want s/_[^.]*_/_/g , or in this case, s/_[^.]*_/_/ would do fine as well.您似乎想要s/_[^.]*_/_/g ,或者在这种情况下, s/_[^.]*_/_/也可以。

  • <<< "new_name" redirects the literal string new_name into sed . <<< "new_name"将文本字符串new_name重定向到sed Possibly you mean <<< "$new_name"可能你的意思是<<< "$new_name"

Personally, though, I would not bother with sed for this job, especially if you have a large number of files.不过,就我个人而言,我不会为这项工作费心使用sed ,尤其是当您有大量文件时。 Bash is perfectly capable of doing fairly complex string manipulation itself, and your needs don't push it too hard. Bash 本身完全有能力进行相当复杂的字符串操作,您的需求不会太强。 Consider:考虑:

for f in *.gz; do
    # The value of $f with the longest trailing match to _* removed
    head=${f%%_*}

    # The value of $f with the longest leading match to *_ removed
    tail=${f##*_}

    new_name="${head}_${tail}"

    # Sanity check and avoid needless errors
    if [ "$f" != "$new_name" ]; then
        mv "$f" "$new_name"
    fi
done

You could do你可以做

for i in *_5*.nii.gz *_6*.nii.gz;do a=${i%%_*};b=${i##*_};[[ $i != $a"_"$b ]] && mv $i $a"_"$b;done

Edited Following suggestion that the file could already be renamed.编辑以下建议该文件已经可以重命名。

Bash's built-in string substitution and its extglob option simplify the replacement of the middle part: Bash 的内置字符串替换及其extglob选项简化了中间部分的替换:

#!/usr/bin/env bash

shopt -s extglob

for file in T1_*.nii.gz; do
  echo mv -- "$file" "${file/_+([^.])_/_}"
done

Remove the echo or pipe the output to a shell, if it matches your expectations.如果符合您的期望,则删除echo或将输出通过管道传输到 shell。

Here is the output of my own test:这是我自己测试的输出:

mv -- T1_0000106_FS1_MAX_5743.nii.gz T1_5743.nii.gz
mv -- T1_0000107_FS1_MAX_5477.nii.gz T1_5477.nii.gz
mv -- T1_0000214_FS1_MAX_5475.nii.gz T1_5475.nii.gz
mv -- T1_0000215_FS1_MAX_6162.nii.gz T1_6162.nii.gz

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM