Bash — locate file, awk copy not working correctly - bash

I'm trying to use the following to locate a file then copy the first result to the directory that is set by $dir. It works fine when I don't set a variable and use an absolute path, but that's not what I need.
This doesn't work:
dir="/path/to/destination/";
mkdir "$dir";
locate -l 1 target_file.txt | awk '{print "cp " $1 $dir " "}' | sh
error message is:
awk: illegal field $(), name "dir"
input record number 1, file
source line number 1
cp: fts_open: No such file or directory
This works:
locate -l 1 target_file.txt | awk '{print "cp " $1 " /path/to/destination/"}' | sh

Inside an awk script, you don't use $ to prefix variables; you use it to refer to fields in the line of input.
dir="/path/to/destination/";
mkdir "$dir";
locate -l 1 target_file.txt | awk -v dir="$dir" '{print "cp", $1, dir}' | sh
This will work OK as long as you have no spaces in your names.
dir="/path/to/destination/";
mkdir "$dir";
locate -l 1 target_file.txt | awk -v dir="$dir" '{printf "cp \"%s\" \"%s\"\n", $1, dir}' | sh
Unless I screwed up the backslashes, that should work with spaces etc in file names. The whole pipeline will be screwed up if someone is unkind enough to put a newline into a file name.

Related

sed: can't read ../../build.gradle: No such file or directory

I am new to git and github. I am working on a project where I need to commit my changes to github repository in a specific branch.
But I am getting the error
$ git commit
3.5.0.1
s/3.5.0.1/3.5.1.1/g
sed: can't read ../../build.gradle: No such file or directory
I have also attached the pre-commit file code here.
#!/bin/sh
## finding the exact line in the gradle file
#ORIGINAL_STRING=$(cat ../../build.gradle | grep -E '\d\.\d\.\d\.\d')
## extracting the exact parts but with " around
#TEMP_STRING=$(echo $ORIGINAL_STRING | grep -Eo '"(.*)"')
## the exact numbering scheme
#FINAL_VERSION=$(echo $TEMP_STRING | sed 's/"//g') # 3.5.0.1
#Extract APK version
v=$(cat build.gradle | grep rtVersionName | awk '{print $1}')
FINAL_VERSION=$(echo ${v} | cut -d"\"" -f2)
echo ${FINAL_VERSION}
major=0
minor=0
build=0
assets=0
regex="([0-9]+).([0-9]+).([0-9]+).([0-9]+)"
if [[ $FINAL_VERSION =~ $regex ]]; then
major="${BASH_REMATCH[1]}"
minor="${BASH_REMATCH[2]}"
build="${BASH_REMATCH[3]}"
assets="${BASH_REMATCH[4]}"
fi
# increment the build number
build=$(echo $build + 1 | bc)
NEW_VERSION="${major}.${minor}.${build}.${assets}"
SED_ARGUMENT=$(echo "s/${FINAL_VERSION}/${NEW_VERSION}/g")
echo $SED_ARGUMENT
sed -i -e `printf $SED_ARGUMENT` ../../build.gradle
The error comes in the last line of this file basically. I am using windows.
Things I tried:
sed -i -e `printf $SED_ARGUMENT` ../../build.gradle
sed -i ' ' -e `printf $SED_ARGUMENT` ../../build.gradle
I am unable to understand where am I actually doing wrong. Kindly help me out.
sed: can't read ../../build.gradle: No such file or directory
This one is rather simple. Your build.gradle file is not at ../../build.gradle.
The solution is to determine actual path to the build.gradle file relative to the script, and change the path in the script.
To debug this, do echo Current Directory: $PWD in the script to see what the actual working directory is, then you should be able to determine the correct path to use.

Using parameters in a shell script

I have a little shell script which goes to a specified Folder and extracts the .tar files in that Folder.
Now,I have to use a parameter to change the path to the Folder.
My first line in my script is cd /bla/bla/bla .
I want to read the /bla/bla/bla part from a separate file. In that file the first line is PATH= /bla/bla/bla.
Anyone got a suggestion for me?
I implemented the solution from Merlin but the script goes into a loop.
My code is:
cd head -n 1 PARAM.TXT | awk -F'=' '{print $2}' | xargs ./pctrl_ExtractAndRemoveTar.sh;
for file in *.tar.gz;
do tmp=${file:34} && b=${tmp%.tar.gz*} && tar tfz "${file}" > "${b}.fl" && tar xzvf "${file}" && rm "${file}";
done
Big thanks,
Tom
Here is how you would use a parameter to your script, which I will call Foo.sh.
#!/bin/bash
pushd "$1"
... Do rest of stuff
popd
When you invoke the script, you would say :
./Foo.sh my/path/goes/here
If you wanted to pull the parameter out of a file, let's say called Bar.txt, you could use head with xargs.
head -n 1 Bar.txt | xargs ./Foo.sh
Note that the line above assumes that the first line of Bar.txt is exactly equal to the path.
If you had the form of varname=the/path, you could grab the right part of the assignment using awk.
head -n 1 Bar.txt | awk -F'=' '{print $2}' | xargs ./Foo.sh
Update: It appears that the OP is calling his own script in an infinite loop, if I am reading his code correctly. Since you seem to want to hardcode PARAM.txt into your script, here is probably what you want.
cd `head -n 1 PARAM.TXT | awk -F'=' '{print $2}'`
for file in *.tar.gz;
do tmp=${file:34} && b=${tmp%.tar.gz*} && tar tfz "${file}" > "${b}.fl" && tar xzvf "${file}" && rm "${file}";
done

Creating a file using parameters of other file using UNIX Shell Script

I have a series of files
484_mexico_201401.dat
484_mexico_201402.dat
484_mexico_201403.dat
… so on
I want to make files
484_mexico_201401.mft which will have below containt
484 | datfile name | line count for the .dat file
Example:
484|484_mexico_201401.dat|6000
can anyone help with a shell script for this ?
You can try bash,
for file in 484_*
do
new_file=${file%.*};
echo "$(sed 's/^\([^_]\+\)_.*/\1/'<<<$file)|$file|$(wc -l $file|cut -d' ' -f1)" > "$new_file.mft";
done
you can also try this.
location="./";for file in $(ls $location);do echo "$(echo $file|cut -d '_' -f 1)|$file|$(wc -l $file | cut -d ' ' -f 1)" >> output.txt;done
Then you will be able to read the new file buy typing cat output.txt
If you want to full script for it, then you may need to add the #!/bin/bash to the first line in the script.
#!/bin/bash
location="./";for file in $(ls $location);do echo "$(echo $file|cut -d '_' -f 1)|$file|$(wc -l $file | cut -d ' ' -f 1)" >> output.txt;done
save that into a file where you want the script to be then run chmod 555 scriptname.sh and you should be able to run.

Illegal variable name on SGE, but not locally.

I have a short bash script running samtools mpileup. It works fine locally, but when I try run it on SGE, I get an "illegal variable name" feedback.
#!/bin/bash
for f in $(find /bed_files -name '*.bed' )
do
name=$(echo $f | awk 'gsub("/", "_")')
name2=$(echo $name | awk 'gsub("_bed_files_", "")')
name3=$(echo $name2 | awk 'gsub(".bed", "")')
samtools runs here
done
Is SGE variable syntax different to bash?
Yes, I needed to change the first line to:
#$ -S /bin/sh

Using DOS file contents as command line arguments in BASH

This is a follow-up to this question's answer.
How can I modify the code so that the annoying CRLF of a DOS created file can be stripped away before being passed to xargs?
Example file 'arglist.dos'.
# cat > arglist.unix
src/file1 dst/file1
src/file2 dst/file2
src/file3 dst/file3
^c
# sed 's/$/\r/' arglist.unix > arglist.dos
The unix variant of the file works with this:
$ xargs -n2 < arglist.unix echo cp
cp src/file1 dst/file1
cp src/file2 dst/file2
cp src/file3 dst/file3
For my own education, how can I change it to accept either the 'arglist.unix' or 'arglist.dos' files on the same command line?
cat arglist.dos | tr -d "\r" | xargs -n2 echo cp
gives you the same result as
cat arglist.unix | tr -d "\r" | xargs -n2 echo cp
so it works on both files.
tr -d "\r" removes all the CR characters
Use d2u to remove the CR before passing the file to xargs.

Resources