bash

时间:2017-11-21 09:18:29

标签: regex bash

我目前正在尝试使用bash正则表达式来同时更改多个文件名。以下是文件名:

a_001_D_xy_S37_L003_R1_001.txt
a_001_D_xy_S37_L003_R2_001.txt
a_002_D_xy_S37_L006_R1_001.txt
a_002_D_xy_S37_L006_R2_001.txt
a_003_D_xy_S23_L003_R1_001.txt
a_003_D_xy_S23_L003_R2_001.txt

我希望这是我的结果:

 a_002_D_xy_R1.txt
 a_002_D_xy_R2.txt
 ...

我只想在最后用* 001.txt更改那些。首先,我想删除_S .._ L00。在文件名和001到底。我将这个程序分为两部分:

for file in *001.txt;
do
echo ${file#_S.._L..6}
done

这个循环已经不起作用了。作为第二种选择,我尝试过:

for file in *001.fastq.gz; 
do
echo ${file/_S.._L00./}
done

但文件名再次不变。 (我只是在这里使用echo来查看结果。如果有效,我将用mv ${file} ${regularexpression}替换它 谢谢你的帮助!

2 个答案:

答案 0 :(得分:1)

考虑到您需要许多不同的字段,最好只分割文件名,然后根据需要重新构建它。

我建议使用通过将原始文件名与_分开构建的数组。然后,您只需使用所需的字段重新构建新名称。

  for file in *001.txt; do
      echo "FILE: $file"

      IFS='_' read -r -a fileFields <<< "$file"
      echo "FILE FIELDS: "
      for index in "${!fileFields[@]}"; do
            echo "- $index ${fileFields[index]}"
      done

      fileName="${fileFields[0]}_${fileFields[1]}_${fileFields[2]}_${fileFields[3]}_${fileFields[-2]}.txt"
      echo "NEW FILE NAME: $fileName"
      # mv $file $fileName
  done

echo命令仅用于调试,一旦您理解了代码,就可以将它们全部删除。

但是,如果你真的需要使用BASH表达式拆分字符串,可以查看这篇文章:  Extracting part of a string to a variable in bash或者查看此BASH cheat sheet

答案 1 :(得分:-1)

尝试创建一个函数,首先要确定文件的数量(n)。

n=$(ls *_001.txt | wc -l)

functionRename(){

  for(( i=1; i <=n; i++))
    do
    file=$(ls *_001.txt | head -n $i | tail -n 1)
    mv "${file}" "${file%_S??_*}${file#???????????????????}"
    file2=$(ls *_001.txt | head -n $i | tail -n 1)
    mv "${file2}" "${file2%_001*}.txt"
    done
}

functionRename