unrar archive then rename the resulting files - rename

My goal is to unrar and rename the resulting files.
test.rar contains
Oldname.txt
Oldname2.txt
... - ...
Output after extracting should be:
Newname.txt
Newname2.txt
... - ...
i make this code but it rename the rar file instead of the extracted files
for f in *.rar
do
unrar x $f;
mv -- "$f" "$(tr '[a-z][A-Z]' '[n-za-m][N-ZA-M]' <<< "$f")" ;
done

The reason for renaming only 'rar' file is that
'$f' is item of '*.rar' collection in the loop, so only that gets renamed.
for f in *.rar
You need to execute a separate loop to iterate the extracted files and then rename them.

Related

Recursively unzip all subdirectories while retaining file structure

I'm new to bash scripting, and i'm finding it hard to solve this one.
I have a parent folder containing a mixture of sub directories and zipped sub directories.
Within those sub directories are also more nested zip files.
Not only are there .zip files, but also .rar and .7z files which also contain nested zips/rars/7zs.
I want to unzip, unrar and un7z all my nested sub directories recursively until the parent folder no longer contains any .rar, .zip, .7zip files. (these eventually need to be removed when they have been extracted). There could be thousands of sub directories all at different nesting depths. You could have zipped folders or zipped files.
However I want to retain my folder structure, so the unzipped folders must stay in the same place where it has been unzipped
I have tried this script that works for unzipping, but it does not retain the file structure.
#!/bin/bash
while [ "`find . -type f -name '*.zip' | wc -l`" -gt 0 ]
do
find . -type f -name "*.zip" -exec unzip -- '{}' \; -exec rm -- '{}' \;
done
I want for example:
folder 'a' contain zipped folder 'b.zip' which contains a zipped text file pear.zip (which is pear.txt that has been zipped to pear.zip a/b.zip(/pear.zip))
I would like folder 'a' to contain 'b' to contain pear.txt 'a/b/pear.txt'
The script above brings 'b' (b is empty) and pear both into folder 'a' where the script is executed which is not what I want. eg 'a/b' and 'a/pear.txt'
You could try this:
#!/bin/bash
while :; do
mapfile -td '' archives \
< <(find . -type f -name '*.zip' -o -name '*.7z' -print0)
[[ ${#archives[#]} -eq 0 ]] && break
for i in "${archives[#]}"; do
case $i in
*.zip) unzip -d "$(dirname "$i")" -- "$i";;
*.7z) 7z x "-o$(dirname "$i")" -- "$i";;
esac
done
rm -rf "${archives[#]}" || break
done
Every archive is listed by find. That list is extracted in the correct location and the archives removed. This repeats, until zero archives are found.
You can add an equivalent unrar command (I'm not familiar with it).
Add -o -name '*.rar' to find, and another case to case. If there's no option to specify a target directory with unrar, you could use cd "$(dirname "$i")" && unrar "$i".
There are some issues with this script. In particular, if extraction fails, the archive is still removed. Otherwise it would cause an infinite loop. You can use unzip ... || exit 1 to exit if extraction fails, and deal with that manually.
It's possible to both avoid removal and also an infinite loop, by counting files which aren't removed, but hopefully not necessary.
I couldn't test this properly. YMMV.

How to gunzip and copy files in a loop

I've a situation where I've to read list of gunzip files (for eg: test.gz, test[2020]*.gz) gunzip them and move it to a different folder(temp). I am using linux bash shell.
So far I've done this:
for f in *.gz
do
gunzip $f
done
When I run the script, the file is successfully gunzipped as test.csv, test[2020].csv respectively.
After that I don't know how to copy the gunzipped files (csv file) to "temp" folder.
Should I open another loop after this code? Or can I gunzip and copy the files in a single loop?
I also want to pause for few minutes between each copy to "temp" folder.
Any help is much appreciated.
Thanks
Remove the .gz suffix from the variable and copy the file with that name.
for f in *.gz
do
gunzip "$f"
cp "${f%.gz}" temp
sleep 60 # sleep 1 minute
done
I think what you want to do is not to copy *.gz file into temp dir. Is it right?
If you use "find", that can work well.
for f in *.gz
do
gunzip $f
mv $(find . -type f -depth 1 \! -name "*.gz") temp
done

How to match partly matching filenames from two directories and execute commands on what found

I'm trying to match two directories and if the file exists in the second directory, I want to move files from the first directory to a third one.
The filenames do not matching exactly, they get a "_ica" at the end of the name and a different extension.
I have tried to write a script that loops through dir1 checks if it's in dir2
and if found move to dir3:
DATA= /home/eegfilesonlyWM/*
PROCESSED= /home/eegfilesonlyWM/icaddata/*
DONE= /home/eegfilesonlyWM/done/
for f in $DATA ; do
fname=${f##*/}
fname=${fname%/}
find /home/eegfilesonlyWM/icaddata/ -iname "${fname*_ica*}" -type f -exec mv {} ./done \;
done
I would like to copy from the first directory those files that already have corresponding files in the second directory.
Thank you for any help
Maybe this will do what you want:
#!/usr/bin/env bash
#Directory paths here
DATA=./DATA
PROCESSED=./PROCESSED
DONE=./DONE
#Do the test and copy here
for f in `ls -1 $DATA`; do
#build output name
p="$PROCESSED/${f/\.xxx/}"; #xxx is the file extension of original
p="${p}_ica.yyy"; #yyy is the file extension of the processed
if [ -f $p ] ; then
cp $DATA/$f $DONE
fi
done

loop cat command for all files and subdirectory

I have lot of mp3 files that are in 2 languages so
language 1 is EN/1/1.mp3 .... .. EN/2/12.mp3
language 2 is DE/1/1.mp3 .... .. DE/2/12.mp3
So files are in same subfolder and same name, I want to merge them
EN/1/1.mp3 and DE/1/1.mp3 to be 1 file and to be saved on folder ENDE/1/1.mp3
I use this command
cat EN/1/1.mp3 DE/1/1.mp3 > ENDE/1/1.mp3
and it works but I want something to that will loop this command to all files in all subfolders.
To loop through the files you can use the following, but as #ekaerovets stated, I believe your file will be invalid.
cd EN
for F in */*.mp3; do
mkdir -p ../ENDE/$(dirname $F)
cat $F ../DE/$F > ../ENDE/$F
done
This is assuming you files are all only one sub directory deep. If the tree is deeper then find would be more appropriate, ie:
cd EN
for F in $(find -type f -name \*.mp3); do
mkdir -p ../ENDE/$(dirname $F)
cat $F ../DE/$F > ../ENDE/$F
done

Extracting specific file types from all tar files from specific folder

I need shell script which accept two arguments.
First one is path to the specific folder and second one is int value (1 or 2).
If second argument is 1 then I have to go through all tar files in mentioned folder and extract just executable files into specific folder inside path from first argument. in this case name of that folder is "unpacked".
If second argument is 2 then I have to extract all *.txt files from all tar files from folder given by first argument.
I am trying something like this but don't know how to catch every tar file and extract one of these two file types.
#!/bin/bash
cd $1
if [$2 –eq 1 ]
then
for f in *.tar; do
tar –xv –f "$f" –-wildcards EXECUTABLE FILES -C ./unpacked
done
fi
if [$2 –eq 2 ]
then
for f in *.tar; do
tar –xv –f "$f" –-wildcards "*.txt" -C ./unpacked
done
fi
The [MEMBER...] argument must come last.
#!/bin/bash
cd $1
if [$2 –eq 1 ]
then
for f in *.tar; do
tar –xv –f "$f" –-wildcards -C ./unpacked EXECUTABLE FILES
done
fi
if [$2 –eq 2 ]
then
for f in *.tar; do
tar –xv –f "$f" –-wildcards -C ./unpacked "*.txt"
done
fi
To Extract specific files form a tar file execute in yor terminal:
$ tar -zxvf TARNAME.tar.gz PATH/FILNAME

Resources