Remove a list of words from filename

独自空忆成欢 提交于 2019-12-03 15:19:14

You can access a file's name as a variable using the 'echo' command. Once that is done, the most powerful way to make your desired changes is to use 'sed'. You can string together sed commands with the '-e' flag. As part of a for loop in bash, this line gives you a start. You can also use a line like this as part of your 'find' statement.

echo $fyle | sed -e 's/FOO//gI' -e 's/BANG//gI'

Once you have your desired file names, you can then move them back to the original name. Let me know if you need more specific instructions.

UPDATE: Here is a more complete solution. You'll have to tune the script to your own file names, etc.

for fyle in $(find . -name "*.*")
do 
   mv -i $fyle `echo $fyle | sed -e 's/FOO//gI' -e 's/BANG//gI' `
done

Finally, to replace more than one whitespace character with one whitespace character, you can add another sed command. Here is a working command:

echo "file    input.txt" | sed 's/  */ /g'

One way to do this will be to add an intermediate step where you generate a file with mv commands to achieve this, and then execute that file. I am assuming you have a words_file file containing words you don't want.

cd to the folder before starting

# Create list of valid <file>s in file_list, and list of "mv <file> " commmands
# in cmd_file
ls | grep -f words_file | tee file_list | sed 's/\(.*\)/mv "\1" /g' > cmd_file

# Create the sed statements using the words_file, store it to sed_commands
# Then, apply the sed commands to file_list
sed 's/\(.*\)/s\/\1\/\/g/g' words_file > sed_commands
sed -f sed_commands file_list > new_file_names

# Combine cmd_file and new_file_names to produce the full mv statements
paste cmd_file new_file_names > final_cmds

# To verify the commands
cat final_cmds

# Finally, execute it
sh final_cmds

This is what I could come up with, it avoids manually writing sed -e for each word. Not sure if there is a simpler way using common bash utilities. Of course, you can use perl or python and write it more concisely.

Edit: Simplified it, did away with eval and xargs.

A script for the task. It accepts at least two arguments, the first one is the list of words to delete from file names, and the rest are the files to process:

perl -MFile::Spec -MFile::Copy -e '
    $words = join( q{|}, split( q| |, shift ) );
    $words_re = qr{$words}i;
    for $path ( @ARGV ) {
        ($dummy, $dir, $f) = File::Spec->splitpath( $path );
        $f =~ s/$words_re//g;
        $f =~ s/\s{2,}/ /g;
        $newpath = File::Spec->catfile( $dir, $f );
        move( $path, $newpath );
        printf qq|[[%s]] renamed to [[%s]]\n|, $path, $newpath;
    }
' "720p BLAH FOO BANG OOO" tmp/user/*.mp4

In my test I had following output:

[[tmp/user/This Awesome Content 720p BLAH FOO BANG OOO - 30.9.2013.mp4]] renamed to [[tmp/user/This Awesome Content - 30.9.2013.mp4]]
Lajos Veres

prename can be useful for the file renaming part. stg similar:

find ... -exec prename 's/(deleteme1|deleteme2|…)//g' {} \;
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!