Renaming files in Shell Script Linux - linux

I want to rename files I have downloaded from the following script:
exec < input_list.txt
while read line
do
get $line
wget ftp://hgdownload.cse.ucsc.edu/goldenPath/hg19/encodeDCC/$2/$4
# Rename $4
mv $4 $1"_"$3".bam"
done
The input file (input_list.txt) is tab delimited and contains four columns. The first, $1= name, $2= wget address, $3= factor and $4 is the file name.
A549 wgEncodeBroadHistone H2azDex100nm wgEncodeBroadHistoneA549H2azDex100nmAlnRep1.bam
I want to rename $4 (the file that has been downloaded) to a shorter file name that only includes the corresponding $1 and $3 terms. For example, wgEncodeBroadHistoneA549H2azDex100nmAlnRep1.bam
becomes A549_H2azDex100nm.bam
I've played around with " but I keep getting error messages for the mv command and that $4 is a bad variable name. Any suggestions would be greatly appreciated.

You don't need to rename the file if you use wget's -O option:
#!/bin/bash
[ -n "$BASH_VERSION" ] || {
echo "You need Bash to run this script."
exit 1
}
while IFS=$'\t' read -a INPUT; do
wget -O "${INPUT[0]}_${INPUT[2]}.bam" "ftp://hgdownload.cse.ucsc.edu/goldenPath/hg19/encodeDCC/${INPUT[1]}/${INPUT[3]}"
done < input_list.txt
Make sure you save the file in UNIX file format like script.sh and run bash script.sh.

Related

List files greater than 100K in bash

I want to list the files recursively in the HOME directory. I'm trying to write my own script , so I should not use the command find or ls. My script is:
#!/bin/bash
minSize=102400;
printFiles() {
for x in "$1/"*; do
if [ -d "$x" ]; then
printFiles "$x";
else
size=$(wc -c "$x");
if [[ "$size" -gt "$minSize" ]]; then
echo "$size";
fi
fi
done
}
printFiles "/~";
So, the problem here is that when I run this script, the terminal throws Line 11: division by 0 and /home/gandalf/Videos/*: No such file or directory. I have not divided by any number, why I'm getting this error?. And the second one?
Alternatively, I can't use find or ls because I have to display the files one by one asking to the user if he want to see the next file or not. This is possible using the command find or ls or only can be done writing my own function?
Thanks.
size=$(wc -c "$x");
That's the line that is failing. When you run that wc command manually you should be able to see why:
$ wc -c /tmp/out
5 /tmp/out
The output contains not only the file size but also the file name. So you can't use $size with the -gt comparator on the next line. One way to fix that is to change the wc line to use cut (or awk, or sed, etc) to keep just the file size.
size=$(wc -c "$x" | cut -f1 -d " ")
A simpler alternative suggested by #mklement0:
size=$(wc -c < "$x")

run shell script on files in multiple directory in linux

I have a shell script which needs to be run on paired files (e.g. file1 and file2). For each pair, there should be 5 output files generated in the current directory. How can I run a shell script on multiple paired files in different directories?
To be more specific, the structure looks like the following:
pair1: /x/y/z/1/file1 and x/y/z/1/file2
pair2: /x/y/z/2/file1 and x/y/z/2/file2
I want to run the same shell script on multiple pairs like these two. The output needs to be saved in the current directory, e.g. /x/y/z/1/ for pair1.
Run the script as:
myscript /x/y/z/1/file1 /x/y/z/1/file2 /x/y/z/2/file1 /x/y/z/2/file2
The script contains:
#!/bin/bash
create_five_files_with_pair() {
cp $1 outfile1
cp $2 outfile2
cat $1 $2 > outfile3
cat $2 $1 > outfile4
paste $1 $2 > outfile5
}
while test $# -gt 1
do
cd $(dirname $1)
create_five_files_with_pair $(basename $1) $(basename $2)
shift
shift
done

Reading specifed file line and creating new directories from words that have been taking of that file

for file in $*
head -n 1 $file | while read folder
do
mkdir $directory $folder
done
Hello guys, I'm having problem with my script. What I want to do is: read first line from my specifed file and create new directories in my specifed directory from words that i have taken from that file.
I'm getting errors like this:
./scriptas: line 2: syntax error near unexpected token `head'
./scriptas: line 2: `head -n 1 $file | while read folder'
And my second question: how do I add a second variable from command line (putty) $directory ?
Example i have file with text:
one two three
five seven nine eleven
okey
i need script to take the first line and create directories "one" "two" "three"
You have to put do before the command in a for/while cycle.
Your code should look like something like this:
#!/bin/bash
files=$*
for file in $files
do
head -n1 "$file" | while read dname
do
mkdir $dname
done
done
as for other variables, the simple syntax is a number behind the $ sign.
so you could do
files="$1"
directory="$2"
and then run the script as
./script.sh "file1.txt file2.txt file3.txt" dir2
More complex solutions include getopts and such....
Updated the script. You can use it in this way:
script.sh "one.txt two.txt three.txt" destdir
#! /bin/bash
for files in $1
do
for i in $(head -n 1 $files)
do
if [ -z $2 ]
then
mkdir $i
else
mkdir $2/$i -p
fi
done
done

Execute and delete command from a file

I have multiple files with an insanely long list of commands. I can't run them all in one go, so I need a smart way to read and execute from file as well as delete the command after completion.
So far I have tried
for i in filename.txt ; do ; execute $i ; sed -s 's/$i//' ; done ;
but it doesn't work. Before I introduced sed, $i was executing. Now even that is not working.
I thought of a workaround where I will read first line and delete first line till file is empty.
Any better ideas or commands?
This should work for you, list.txt is your file containing commands.
Make sure you backup the command file before running.
while read line; do $line;sed -i '1d' list.txt;done < "list.txt"
sed -i edits in-place so list.txt will be changed along the loop and you will end up with a empty file.
I think what you want to do is something like this:
while read -r -- i; do $i; sed -i "0,/$i/s/$i//;/^$/d" filename.txt; done < filename.txt
The file is read into the loop. Each line is executed, and the sed command will delete only the first entry it finds, then delete the empty line.
I think that one way to do it is to have the source file of all the commands to be executed, and the script that executes the commands also writes a second log file that lists the files as they are executed.
If you need to resume the process, you work on the lines in the source file that are not present in the log file.
logfile=commands.log
srcfile=commands.src
oldfile=commands.old
trap "mv $oldfile $logfile; exit 1" 0 1 2 3 13 15
[ -f $logfile ] || cp /dev/null $logfile
cp $logfile $oldfile
comm -23 $srcfile $logfile |
while read -r line
do
echo "$line" >> $oldfile
($line) < /dev/null
done
mv $oldfile $logfile
trap 0

Storing directory as a variable for later use in linux script

In my script, I am holding the location (path) of a file as a variable.
For example, fileA
An example of its contents are
fileA=/usr/anotherfolder/somefold/"filenamehere"
However, when i call a command on the file in the script such as:
cat $fileA
or
cat "$fileA"
I get an error saying the file or directory doesn't exist. If I echo $fileA to see what the output is, and then run a cat manually from the terminal, it works fine, don't know what is going wrong. Any help?
Some debug info:
fileA='/home/jacob/Desktop/CS35L/WORK/2/hw/test3/"new"'
echo '/home/jacob/Desktop/CS35L/WORK/2/hw/test3/"new"'
/home/jacob/Desktop/CS35L/WORK/2/hw/test3/"new"
'[' '!' -r '/home/jacob/Desktop/CS35L/WORK/2/hw/test3/"new"' ']'
For these particular lines
Check for readable file
echo $fileA
if [ ! -r "$fileA" ]
then
o=`expr $o + 1`
echo "$fileA not readable."
continue
fi
If file name is new(not "new"), then change
fileA='/home/jacob/Desktop/CS35L/WORK/2/hw/test3/"new"'
to
fileA=/home/jacob/Desktop/CS35L/WORK/2/hw/test3/new

Resources