batch renaming of files with perl expressions

纵然是瞬间 提交于 2021-01-27 05:27:27

问题


This should be a basic question for a lot of people, but I am a biologist with no programming background, so please excuse my question.

What I am trying to do is rename about 100,000 gzipped data files that have existing name of a code (example: XG453834.fasta.gz). I'd like to name them to something easily readable and parseable by me (example: Xanthomonas_galactus_str_453.fasta.gz).

I've tried to use sed, rename, and mmv, to no avail. If I use any of those commands on a one-off script then they work fine, it's just when I try to incorporate variables into a shell script do I run into problems. I'm not getting any errors, just no names are changed, so I suspect it's an I/O error.

Here's what my files look like:

#! /bin/bash
# change a bunch of file names
file=names.txt

while IFS=' '  read -r r1 r2;
do
    mmv ''$r1'.fasta.gz' ''$r2'.fasta.gz'
    # or I tried many versions of: sed -i 's/"$r1"/"$r2"/' *.gz
    # and I tried many versions of: rename -i 's/$r1/$r2/' *.gz

done < "$file"

...and here's the first lines of my txt file with single space delimiter:

    cat names.txt

   #find #replace 
   code1 name1
   code2 name2
   code3 name3

I know I can do this with python or perl, but since I'm stuck here working on this particular script I want to find a simple solution to fixing this bash script and figure out what I am doing wrong. Thanks so much for any help possible.

Also, I tried to cat the names file (see comment from Ashoka Lella below) and then use awk to move/rename. Some of the files have variable names (but will always start with the code), so I am looking for a find & replace option to just replace the "code" with the "name" and preserve the file name structure.

I suspect I am not escaping the variable within the single tick of the perl expression, but I have poured over a lot of manuals and I can't find the way to do this.


回答1:


If you're absolutely sure than the filenames doesn't contain spaces of tabs, you can try the next

xargs -n2 < names.txt echo mv

This is for DRY run (will only print what will do) - if you satisfied with the result, remove the echo ...

If you want check the existence ot the target, use

xargs -n2 < names.txt echo mv -i

if you want NEVER allow overwriting of the target use

xargs -n2 < names.txt echo mv -n

again, remove the echo if youre satisfied.




回答2:


I don't think that you need to be using mmv, a simple mv will do. Also, there's no need to specify the IFS, the default will work for you:

while read -r src dest; do mv "$src" "$dest"; done < names.txt

I have double quoted the variable names as it is generally considered good practice but in this case, a space in either of the filenames will result in read not working as you expect.

You can put an echo before the mv inside the loop to ensure that the correct command will be executed.

Note that in your file names.txt, the .fasta.gz suffix is already included, so you shouldn't be adding it inside the loop aswell. Perhaps that was your problem?




回答3:


This should rename all files in column1 to column2 of names.txt. Provided they are in the same folder as names.txt

cat names.txt| awk '{print "mv "$1" "$2}'|sh


来源:https://stackoverflow.com/questions/25711833/batch-renaming-of-files-with-perl-expressions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!