Why does script not recognize file extension? - linux

My script
#!/bin/bash
cp *.ats /home/milenko/procmt
mycd() {
cd /home/milenko/procmt
}
mycd
EXT=ats
for i in *; do
if [ "${i}" != "${i%.${EXT}}" ];then
./tsmp -ascii i
fi
done
But
milenko#milenko-HP-Compaq-6830s:~/Serra do Mel/MT06/meas_2016-07-13_20-22-00$ bash k1.sh
./tsmp: handling 1 files ************************************** total input channels: 1
the name of your file does not end with ats ... might crash soon
main (no rda) -> can not open i for input, exit
./tsmp: handling 1 files ************************************** total input channels: 1
the name of your file does not end with ats ... might crash soon
main (no rda) -> can not open i for input, exit
When I go to procmt directory and list files
milenko#milenko-HP-Compaq-6830s:~/procmt$ ls *.ats
262_V01_C00_R000_TEx_BL_2048H.ats 262_V01_C00_R086_TEx_BL_4096H.ats 262_V01_C02_R000_THx_BL_2048H.ats
262_V01_C00_R000_TEx_BL_4096H.ats 262_V01_C01_R000_TEy_BL_2048H.ats 262_V01_C03_R000_THy_BL_2048H.ats
What is wrong with my script?

If I understand correctly this should work for you:
dest='/home/milenko/procmt'
cp *.ats "$dest"
cd "$dest"
for i in *.ats; do
./tsmp -ascii "$i"
done
There is no need to loop through all files when you're only interested in .ats files. Your mycd function is just doing cd so you can avoid that as well.

Related

Execute function for every subfolder

I have a folder named students_projects that contains 10 subfolders. Each subfolder has project1.c and project2.c, each one prints a value. I made a bash script function that check those numbers and save them to a txt file. I tested it with 2 .c files named project1 and project2 in Desktop and not in the folder. I made sure that i worked fine but when i went to run it for all the subfolders it keeps saving the values that are in desktop files.
My function:
function test () {
gcc project1.c
p1=$(./a.out)
if (( $p1 == 20 ));
then
v1=30
else
v1=0
fi
gcc project2.c
p2=$(./a.out)
if (($p2 == 10 ));
then
v2=70
else
v2=0
fi
sum=$(( $v1 + $v2 ))
on="cut -d' ' -f1 report.txt"
onoma=$(eval "$on")
temp="cut -d' ' -f2 report.txt"
am=$(eval "$temp")
printf "$onoma $am project1: $v1 project2: $v2 total_grade: $sum\n" >> grades.txt
}
Then i do
for FILE in students_projects/* ; do
test
done
Looks like the grades.txt file is at the top level, but you want to run test under each directory. The easiest change is to pass a full path to $PWD/grades.txt to the function. Coombine that with running "cd" into each subdir. Recommendation:
for FILE in students_projects/* ; do
(cd $FILE; test $PWD/grades.txt)
done
Then in your "function test()", use that $1 argument instead of grades.txt:
printf "..." >> $1

linux command rename dates (YYYY.MMDD) to numbers(001,002,...,066,067) sequentially

I have renamed many files by using 'rename'.
However, I find a problem with conversion dates to numbers.
The file name is 2021.0801, 2021.0802, .. etc. (Year.Month&date)
I need to change Month&date parts to numbers of 001, 002, etc.
So I need to rename
2021.0801
2021.0802
...
2021.0929
2021.0930
to
2021.001
2021.002
...
2021.0**
2021.0**
I saw I can do it when I use rename or #, ? but I could not see the specific way to solve this.
Could you please let me know the way to rename these?
p.s. I tried num=001; for i in {0801..0930}; do rename $i $num *; (($num++)); done but it showed
2021.001
2021.001001
2021.001001001001
...
Additionally, ls 2021.* shows only the files that I want to change.
Your script contains a few errors. I suggest to use https://www.shellcheck.net/ to check your scripts.
After fixing the errors, the (unfinished) result is
#!/bin/bash
num=001; for i in {0801..0930}; do rename "$i" "$num" ./*; ((num++)); done
This has 3 remaining problems.
The range {0801..0930} includes the numbers 0831, 0832, ... 0899, 0900. This can be fixed by using two ranges {0801..0831} {0901..0930}
The increment operation ((num++)) does not preserve the leading zeros. This can be fixed by conditionally adding 1 or 2 zeros.
You call rename for every combination which will check all files and probably rename only one. As you know the exact file names you can replace this with a mv command.
The final version is
num=1; for i in {0801..0831} {0901..0930}; do
if [[ num -lt 10 ]] ; then
new="00$num";
elif [[ num -lt 100 ]] ; then
new="0$num";
else
new="$num"; # this case is not necessary here
fi;
mv "2021.$i" "2021.$new";
((num++));
done
The script handles leading zeros for values of 1, 2 or 3 digits which is not needed here as all numbers are less than 100. For this case, it can be simplified as
num=1; for i in {0801..0831} {0901..0930}; do
if [[ num -lt 10 ]] ; then
new="00$num";
else
new="0$num";
fi;
mv "2021.$i" "2021.$new";
((num++));
done
The script will execute these commands:
mv 2021.0801 2021.001
mv 2021.0802 2021.002
...
mv 2021.0830 2021.030
mv 2021.0831 2021.031
mv 2021.0901 2021.032
mv 2021.0902 2021.033
...
mv 2021.0929 2021.060
mv 2021.0930 2021.061
You don't need the for loop. This single command will do it all :
rename -n 'BEGIN{our $num=1}{our $num;s/\d+$/sprintf("%03d", $num)/e; $num += 1}' 2021.*
Remove -n once the resulting renaming looks good.

Concatenate a string with an array for recursively copy file in bash

I have a concatenation problem between a string and an array
I want to copy all the files contained in the directories stored in the array, my command is in a loop (to recursively copy my files)
yes | cp -rf "./$WORK_DIR/${array[$i]}/"* $DEST_DIR
My array :
array=("My folder" "...")
I have in my array several folder names (they have spaces in their names) that I would like append to my $WORK_DIR to make it possible to copy the files for cp.
But I always have the following error
cp: impossible to evaluate './WORKDIR/my': No such files or folders
cp: impossible to evaluate 'folder/*': No such files or folders
This worked for me
#!/bin/bash
arr=("My folder" "This is a test")
i=0
while [[ ${i} -lt ${#arr[#]} ]]; do
echo ${arr[${i}]}
cp -rfv ./source/"${arr[${i}]}"/* ./dest/.
(( i++ ))
done
exit 0
I ran the script. It gave me the following output:
My folder
'./source/My folder/blah-folder' -> './dest/./blah-folder'
'./source/My folder/foo-folder' -> './dest/./foo-folder'
This is a test
'./source/This is a test/blah-this' -> './dest/./blah-this'
'./source/This is a test/foo-this' -> './dest/./foo-this'
Not sure of the exact difference, but hopefully this will help.

bash: How to transfer/copy only the file names to separate similar files?

I've some files in a folder A which are named like that:
001_file.xyz
002_file.xyz
003_file.xyz
in a separate folder B I've files like this:
001_FILE_somerandomtext.zyx
002_FILE_somerandomtext.zyx
003_FILE_somerandomtext.zyx
Now I want to rename, if possible, with just a command line in the bash all the files in folder B with the file names in folder A. The file extension must stay different.
There is exactly the same amount of files in each folder A and B and they both have the same order due to numbering.
I'm a total noob, but I hope some easy answer for the problem will show up.
Thanks in advance!
ZVLKX
*Example edited for clarification
An implementation might look a bit like this:
renameFromDir() {
useNamesFromDir=$1
forFilesFromDir=$2
for f in "$forFilesFromDir"/*; do
# Put original extension in $f_ext
f_ext=${f##*.}
# Put number in $f_num
f_num=${f##*/}; f_num=${f_num%%_*}
# look for a file in directory B with same number
set -- "$useNamesFromDir"/"${f_num}"_*.*
[[ $1 && -e $1 ]] || {
echo "Could not find file number $f_num in $dirB" >&2
continue
}
(( $# > 1 )) && {
# there's more than one file with the same number; write an error
echo "Found more than one file with number $f_num in $dirB" >&2
printf ' - %q\n' "$#" >&2
continue
}
# extract the parts of our destination filename we want to keep
destName=${1##*/} # remove everything up to the last /
destName=${destName%.*} # and past the last .
# write the command we would run to stdout
printf '%q ' mv "$f" "$forFilesFromDir/$destName.$f_ext"; printf '\n'
## or uncomment this to actually run the command
# mv "$f" "$forFilesFromDir/$destName.$f_ext"
done
}
Now, how would we test this?
mkdir -p A B
touch A/00{1,2,3}_file.xyz B/00{1,2,3}_FILE_somerandomtext.zyx
renameFromDir A B
Given that, the output is:
mv B/001_FILE_somerandomtext.zyx B/001_file.zyx
mv B/002_FILE_somerandomtext.zyx B/002_file.zyx
mv B/003_FILE_somerandomtext.zyx B/003_file.zyx
Sorry if this isn't helpful, but I had fun writing it.
This renames items in folder B to the names in folder A, preserving the extension of B.
A_DIR="./A"
A_FILE_EXT=".xyz"
B_DIR="./B"
B_FILE_EXT=".zyx"
FILES_IN_A=`find $A_DIR -type f -name *$A_FILE_EXT`
FILES_IN_B=`find $B_DIR -type f -name *$B_FILE_EXT`
for A_FILE in $FILES_IN_A
do
A_BASE_FILE=`basename $A_FILE`
A_FILE_NUMBER=(${A_BASE_FILE//_/ })
A_FILE_WITHOUT_EXTENSION=(${A_BASE_FILE//./ })
for B_FILE in $FILES_IN_B
do
B_BASE_FILE=`basename $B_FILE`
B_FILE_NUMBER=(${B_BASE_FILE//_/ })
if [ ${A_FILE_NUMBER[0]} == ${B_FILE_NUMBER[0]} ]; then
mv $B_FILE $B_DIR/$A_FILE_WITHOUT_EXTENSION$B_FILE_EXT
break
fi
done
done

Try to change files name in bash

I'm trying my first program in BASH
The program needs to change the files name in directory.
The first argument is base name and the second argument is a file extension
If I call to the function with:
rename Test jpg
then the resulting files should have names like:
Test001.jpg, Test002.jpg, Test003.jpg,...
What I tried:
function rename {
index=0
for i in $1"/"*".$2"; do
newName=$(printf $1/"$1%04d."$2 ${index})
mv $i $newName
let index=index+1
done
}
And when I call to the function
bash rename.sh pwd jpg
And nothing dosen't happened,please help me:)
What I would do :
rn(){
for i in $1*.$2; do
((index++))
newName=$(printf "$1%04d.$2" $index)
mv $i $newName
done
}
cd WHERE/YOU/WANT
rn "$#"

Resources