paste text to filenames in unix - unix

I have a list of strings in String that I want to add at the beginning of all files names of Targets in the folder. All files are ordered.
String.txt:
ID1Somestring_
IDISomeOtherString_
IDISomeThirdString_
Targets:
example1.fastq
example2.fastq
example3.fastq
output:
ID1Somestring_example1.fastq
IDISomeOtherString_example2.fastq
IDISomeThirdString_example3.fastq

First, read the file into an array
mapfile -t strings < String.txt
Then, iterate over the files and access each array element in turn:
n=0; for file in *fastq; do echo mv "$file" "${strings[n++]}$file"; done
mv example1.fastq ID1Somestring_example1.fastq
mv example2.fastq IDISomeOtherString_example2.fastq
mv example3.fastq IDISomeThirdString_example3.fastq
Or, assuming your filenames do not contain newlines
paste String.txt <(printf "%s\n" *fastq) |
while read -r string file; do echo mv "$file" "$string$file"; done

Related

script to watch new files in a folder and when found, based on filename call different scripts

I am trying to design a file watcher solution in which I need to watch a particular folder for different file names everyday, once the file name is found, I need to call a script specific to the file name.
Example:
Watch Folder -
file1.txt
file2.txt
file3.txt
call script.sh abc file1
call script.sh abc file2
call script.sh abc file3
I tried to make use of the inotifywait but have not been able to get it to work. Any help would be appreciated.
sftp_home=/app/public/ent_sftp
script=/app/public/bin
curr_date=$(TZ=":US/Eastern" date '+%Y%m%d')
inotifywait -m $sftp_home -e create -e moved_to |
while read path action file; do
echo "The file '$file' appeared in directory '$path' via '$action'"
if [ "$file" = "file1${curr_date}*.txt" ]; then
echo "file1${curr_date}*.txt was found and process will be initiated"
cd $script
./script.sh file1
elif [ "$file" = "file2${curr_date}*.txt" ]; then
echo "file2${curr_date}*.txtwas found today and process will be initiated"
cd $script
./script.sh file2
fi
done
Thanks,
Kavin
If you want to do glob expansions in the match, you can do that with a case statement:
unset arg
case $file in
file1${curr_date}*.txt)
arg=file1
;;
file2${curr_date}*.txt)
arg=file2
;;
*)
echo No file found >&2
;;
esac
if test -n "$arg"; then
echo "${arg}${curr_date}*.txt was found and process will be initiated"
cd $script
./script.sh "$arg"
fi

To print GunZip FileName and selected rows -Continuation :

Would like to print first 2 rows from all the files located in the directory along with File Name.
All are *.gz extension files. Having around 100 files in that directory.
sample_jan.csv.gz
10,Jan,100
30,Jan,300
50,Jan,500
sample_feb.csv.gz
10,Feb,200
20,Feb,400
40,Feb,800
60,Feb,1200
Expected Output:
Filename:sample_jan.csv.gz
10,Jan,100
30,Jan,300
Filename:sample_feb.csv.gz
10,Feb,200
20,Feb,400
Tried below command where as Filename appears Blank
zcat sample_jan.csv.gz | awk 'FNR==1{print "Filename:" FILENAME} FNR<3' > Output.txt
Filename:-
10,Jan,100
30,Jan,300
Tried below command where as Filename appears Wrong
awk 'FNR==1{print "Filename:" FILENAME} FNR<3' <(gzip -dc sample_jan.csv.gz) > Output.txt
Filename:/dev/fd/63
10,Jan,100
30,Jan,300
Looking for your suggestions, dont have perl & python.
You can use this one-liner,
for file in *.gz; do echo "Filename: $file"; zcat "$file" | head -2 ; done

Batch rename files if they don't contain a character

I have audio files names either 'A_B.wav' or 'A.wav'. I'd like to rename all files with a filename in the format 'A.wav' to 'A_A.wav' and leave all other files unchanged.
In other words, I need to batch rename only files that contain no underscore.
Is there a way to do this via the Linux console?
#!/bin/bash
for i in *;
do
j=`echo $i | cut -d . -f 1`;
e=`echo $i | cut -d . -f 2`;
if [[ $j != *_* ]]
then
j=$j"_"$j"."$e;
mv $i $j;
fi
done

searching for part of a filename (UNIX)

On unix I have files which have been renamed as their original name follwed by _inode number (ie the file dog would be renamed dog_inodeno). I am now trying to remove the inode no so i can search for the original file name elsewhere. Does anyone know how I can do this and teh coding neccesary.
Thanks
This should do the job:
find . -type f -name "*_[0-9]*" -exec \
sh -c 'for i do
b=$(basename "$i")
r=$(basename "$i" "_$(ls -i "$i"|awk "{print \$1}")")
if [ "$b" != "$r" ]; then
echo mv "$i" "$(dirname $i)/$r"
fi
done' sh {} +
Replace echo mv by mv for the script to actually rename the files.
The solution here will do rename your files only if the inode number of a file is part of the file's name in the mentioned format, which is what the OP wants.
Solution is successfuly tested at my end.
find ./ -name "*_[0-9][0-9][0-9][0-9][0-9][0-9]" -exec sh 'rename-files.sh' {} \;
Store the below script for the find command to be successful.
#Script Name: rename-files.sh
#!/bin/bash
#Store the result of find
find_result=$1
#Get the existing file name
fname_alone=`expr ${find_result} : '.*/\(.*\)' '|' ${find_result}`
fname_with_relative_path=`expr ${find_result} : '.\(.*\)' '|' ${find_result}`
fname_with_full_path=`echo "$(pwd)${fname_with_relative_path}"`
#Get the inode number of file name
file_inode_no=`find ./ -name ${fname_alone} -printf '%i'`
#Read the end of name
end_of_name=`echo $fname_alone | awk -F "_" '{print $NF}' `
#Check if end of name contains its file's inode number
if [ $end_of_name -eq $file_inode_no ]
then
#Remove the inode number at the end of file name
new_name=`expr $find_result : '.\(.*\)_.*' '|' $find_result`
#Append the path of the file
renamed_to=`echo "$(pwd)${new_name}"`
#Rename your dog_inodeno to dog
mv $fname_with_full_path $renamed_to
fi
Hope this helps.

how to copy the dynamic file name and append some string while copying into other directory in unix

I have many files like ABC_Timestamp.txt , RAM_Timestamp.txthere timestamp will be different everytime. I want to copy this file into other directory but while copying I want append one string at the end of the file , so the format will be ABC_Timestamp.txt.OK and RAM_Timestamp.txt.OK. How to append the string in dynamic file. Please suggest.
My 2 pence:
(cat file.txt; echo "append a line"; date +"perhaps with a timestamp: %T") > file.txt.OK
Or more complete for your filenames:
while sleep 3;
do
for a in ABC RAM
do
(echo "appending one string at the end of the file" | cat ${a}_Timestamp.txt -) > ${a}_Timestamp.txt.OK
done
done
Execute this on command line.
ls -1|awk '/ABC_.*\.txt/||/RAM_.*\.txt/
{old=$0;
new="/new_dir/"old".OK";
system("cp "old" "new); }'
Taken from here
You can say:
for i in *.txt; do cp "${i}" targetdirectory/"${i}".OK ; done
or
for i in ABC_*.txt RAM_*.txt; do cp "${i}" targetdirectory/"${i}".OK ; done
How about first dumping the names of the file in another file and then moving file one by one.
find . -name "*.txt" >fileNames
while read line
do
newName="${line}appendText"
echo $newName
cp $line $newName
done < fileNames

Resources