替换/替换bash中文件名列表中的子串列表(使用awk?)

时间:2018-04-26 09:28:36

标签: bash awk substring filenames substitution

我发现在我的一些> 100.000文件名我的分隔符_也出现在预期的位置上并且弄乱了处理。因此,我想替换这些文件中的_。它们都在一个文件夹中。我尝试使用awk FILENAME变量,但我不知道如何通过它来更改文件名本身。例如,完整的文件名。

mg.reads.per.gene_Putative@polyhydroxyalkanoic@acid@system@protein@(PHA_gran_rgn)_A1.tsv   
mg.reads.per.gene_Phage@regulatory@protein@Rha@(Phage_pRha)_A1.tsv 
...

一般来说,第一个和最后一个_应该在那里,所有其他的应该被替换。注意:附加的并不总是在括号中。我生成了一个列表,其中包含名为problems.txt的文件名中有问题的子字符串:

Putative@polyhydroxyalkanoic@acid@system@protein@(PHA_gran_rgn)
Phage@regulatory@protein@Rha@(Phage_pRha)
Phage@tail@protein@(Tail_P2_I)
Phd_YefM
pheT_bact:@phenylalanine--tRNA@ligase%2C@beta@subunit
...

并且此处也希望使用@作为非常见的角色来获取:

mg.reads.per.gene_Putative@polyhydroxyalkanoic@acid@system@protein@(PHA@gran@rgn)_A1.tsv    
mg.reads.per.gene_Phage@regulatory@protein@Rha@(Phage@pRha)_A1.tsv 
...

如何使用此列表作为输入来仅更改与列表中的记录匹配的文件名?我试过这个来修改文件夹中的文件并更改部分文件名(awk Pseudocode):

for sample_files in $(find . -mindepth 1 -maxdepth 1 -type f)
do  
  awk '{if ("problem_record" ~ FILENAME); 
  gsub(/_/,/@/, substring(FILENAME))); print}' problems.txt $sample_files > $sample_files
done

但是我不能指定我只想要在" problem_record"所涵盖的范围内进行更改。条目。我也不知道如何指定输出

1 个答案:

答案 0 :(得分:1)

这是一个纯粹的bash解决方案:

#!/bin/bash

# Loop over all files in the current directory
for i in *; do

  # Extract the part before the first _
  head="${i%%_*}"

  # Get the rest of the string
  tail="${i#*_}"

  # Extract the part after the last _
  rhead="${tail##*_}"

  # Extract the "middle" portion
  rtail="${tail%_*}"

  # Substitute _ with @ in the "middle"
  fixedrtail="${rtail//_/@}"

  # Rename files
  #echo -e "Renaming \"$i\" to \"$head_${fixedrtail}_$rhead\""
  mv $i "${head}_${fixedrtail}_${rhead}"
done

这将获取当前目录中的所有文件并重命名,以便除{1}}之外的所有_除外。@。它使用了大量参数扩展,您可以read about here