cygpath inconsistent with variable as input unix to windows conversion - windows

I have a bash script that prompts a user to drag and drop a file as an input and then I need to convert that path to windows style path so I can use it as an argument to an .exe that is being called:
echo -e "\nPlease drag and drop your input audio file into this window and hit Enter\n"
read inputfile
inputfilewin=$(cygpath -w -a "${inputfile}")
echo "inputfile: $inputfile"
echo "inputfilewin: $inputfilewin"
This works fine for paths with no spaces but my Box Sync folder produces a response like this:
C:\cygwin\home\jimbob\'\cygdrive\c\Users\jimbob\Box Sync\myscripts\testscript\6ch.wav'
but if i just type on the command line cygpath -w -a and drag and drop the same file i get the right path back:
C:\Users\jimbob\Box Sync\myscripts\testscript\6ch.wav
Please help I just can't get it to work how I need

$ echo $a
/cygdrive/c/Program Files/Autodesk/DWG TrueView 2016 - English
so depending on how many escape you need:
$ cygpath -w "$(echo -n $a |sed -e 's/ /\ /g')"
C:\Program Files\Autodesk\DWG TrueView 2016 - English
$ cygpath -w "$(echo -n $a |sed -e 's/ /\\ /g')"
C:\Program\ Files\Autodesk\DWG\ TrueView\ 2016\ -\ English

Related

Checking file existence in Bash using commandline argument

How do you use a command line argument as a file path and check for file existence in Bash?
I have the simple Bash script test.sh:
#!/bin/bash
set -e
echo "arg1=$1"
if [ ! -f "$1" ]
then
echo "File $1 does not exist."
exit 1
fi
echo "File exists!"
and in the same directory, I have a data folder containing stuff.txt.
If I run ./test.sh data/stuff.txt I see the expected output:
arg1=data/stuff.txt
"File exists!"
However, if I call this script from a second script test2.sh, in the same directory, like:
#!/bin/bash
fn="data/stuff.txt"
./test.sh $fn
I get the mangled output:
arg1=data/stuff.txt
does not exist
Why does the call work when I run it manually from a terminal, but not when I run it through another Bash script, even though both are receiving the same file path? What am I doing wrong?
Edit: The filename does not have spaces. Both scripts are executable. I'm running this on Ubuntu 18.04.
The filename was getting an extra whitespace character added to it as a result of how I was retrieving it in my second script. I didn't note this in my question, but I was retrieving the filename from folder list over SSH, like:
fn=$(ssh -t "cd /project/; ls -t data | head -n1" | head -n1)
Essentially, I wanted to get the filename of the most recent file in a directory on a remote server. Apparently, head includes the trailing newline character. I fixed it by changing it to:
fn=$(ssh -t "cd /project/; ls -t data | head -n1" | head -n1 | tr -d '\n' | tr -d '\r')
Thanks to #bigdataolddriver for hinting at the problem likely being an extra character.

sed pattern matching not working

I'm trying to create a bash script to automate extracting tar archives and my sed regex is not acting as expected. If I do:
archive=$1
directory=$(sed "s/.tar.bz2$//" <<< $archive)
echo "extracting $archive to $directory"
I get :
$ sh extract binutils-2.27.tar.bz2
extracting binutils-2.27.tar.bz2 to binutils-2.27
which is as expected.
But if I do :
archive=$1
directory=$(sed "s/.tar.[a-z0-9]{2,3}$//" <<< $archive)
echo "extracting $archive to $directory"
which is what I want to do (so as to handle any type of archive), I'd expect to get the same output, but I'm getting :
$ sh extract binutils-2.27.tar.bz2
extracting binutils-2.27.tar.bz2 to binutils-2.27.tar.bz2
As you can see the regex is not applying.
I've tested my regex on regex101.com and it seems to be correct, but it doesn't seem to be working correctly in the bash script. Can someone point me in the right direction as to what is going wrong please.
I'm on Mint 17.3.
The sed based solution would be:
directory=$(sed -E 's/\.tar\.[a-z0-9]{2,3}$//' <<< $archive)
however, with some assumptions, you can use bash features only:
directory=${archive%.tar.*}
You need the -E flag on sed:
$ archive=binutils-2.27.tar.bz2
$ directory=$( sed "s/.tar.[a-z0-9]{2,3}$//" <<< $archive)
$ echo $directory
binutils-2.27.tar.bz2
$ directory=$( sed -E "s/.tar.[a-z0-9]{2,3}$//" <<< $archive)
$ echo $directory
binutils-2.27

Readlink - How to crop full path?

I use readlink to find a file's full path:
cek=$(readlink -f "$1")
mkdir -p "$ydk$cek"
mv "$1" "$ydk/$cek/$ydkfile"
But readlink -f "$1" gives me the full path. How can I crop the full path?
For example:
/home/test/test/2014/10/13/log.file
But I need just
/test/2014/10/13/
How can I do it?
Judging from multiple comments:
The output should be the last four directory components of the full path returned by readlink.
Given:
full_path=/home/some/where/hidden/test/2014/08/29/sparefile.log
the output should be:
test/2014/08/29
(Don't build any assumption about today's date into the path trimming code.)
If you need the last four directory components of the full path, and if you don't have newlines in the full path, and if you have GNU grep or BSD (Mac OS X) grep with support for -o (output only the matched material) then this gives the required result:
$ cek="/home/test/test/2014/10/13/log.file"
$ echo "${cek%/*}"
/home/test/test/2014/10/13
$ echo "${cek%/*}" | grep -o -E -e '(/[^/]+){4}$'
/test/2014/10/13
$ full_path=/home/some/where/hidden/test/2014/08/29/sparefile.log
$ echo "${full_path%/*}" | grep -o -E -e '(/[^/]+){4}$'
/test/2014/08/29
$
I need path starting /201[0-9]:
/home/bla/bla2/bla3/2014/01/13/13… ⟶ /2014/01/13/13….
So, you need to use grep -o again, starting with the year pattern:
echo "${fullpath%/*}" | grep -o -e '/201[0-9]/.*$'
This is much simpler; you don't even need extended regular expressions for this!
If you need the path element before the year too, then you need:
echo "{fullpath%/*}" | grep -o -e '/[^/][^/]*/201[0-9]/.*$'
Do you really need to remove "/home" ?
cek="/home/test/test/2014/10/13/log.file"
dir=$(dirname "$cek")
echo "${dir#/home}"
/test/test/2014/10/13
Just last 4 directory components:
last4dirs() {
local IFS=/
local -a components=($1)
local l=${#components[#]}
echo "${components[*]:l-5:4}"
}
last4dirs /home/some/where/hidden/test/2014/08/29/sparefile.log
test/2014/08/29

bash cut to variable and cd

Hi i am having a really strange problem.
I am trying to run the following scrip as root:
loc=$(transmission-remote 192.168.1.74:9091 --auth=user:password -t$TORRENTID -i |sed -e '1d;$d;s/^ *//'|grep Location: |cut -s -d : -f2)
cd "$loc"
But get the error messege :
cd: can't cd to /leprechaun_tv-shows/download/
But i works if i create a new string:
hello= /leprechaun_tv-shows/download/
cd $hello
what am i doing wrong?
Why are you quoting "$loc" ?
If $loc has a leading space, then quoting the variable expansion will pass the directory with that leading space as an argument.
e.g. cding to root in this fashion gives me:
$ cd " /"
cd: no such file or directory: /
Just remove the quoting. e.g.
cd $loc
Alternatively to Brian's solution, if you still need $loc to be quoted in cd "$loc" because the path could contain any spaces, then just use sed 's/^ *//g' to trim any leading spaces in $loc, like this:
loc=$(transmission-remote 192.168.1.74:9091 --auth=user:password -t$TORRENTID -i |sed -e '1d;$d;s/^ *//'|grep Location: |cut -s -d : -f2 | sed 's/^ *//g')
cd "$loc"
Since it appears you have some initial whitespace in $loc, you can trim it with bash's parameter expansion:
loc=$(transmission-remote 192.168.1.74:9091 --auth=user:password -t$TORRENTID -i |sed -e '1d;$d;s/^ *//'|grep Location: |cut -s -d : -f2)
cd "${loc%% }"

creating a file downloading script with checksum verification

I want to create a shellscript that reads files from a .diz file, where information about various source files are stored, that are needed to compile a certain piece of software (imagemagick in this case). i am using Mac OSX Leopard 10.5 for this examples.
Basically i want to have an easy way to maintain these .diz files that hold the information for up-to-date source packages. i would just need to update these .diz files with urls, version information and file checksums.
Example line:
libpng:1.2.42:libpng-1.2.42.tar.bz2?use_mirror=biznetnetworks:http://downloads.sourceforge.net/project/libpng/00-libpng-stable/1.2.42/libpng-1.2.42.tar.bz2?use_mirror=biznetnetworks:9a5cbe9798927fdf528f3186a8840ebe
script part:
while IFS=: read app version file url md5
do
echo "Downloading $app Version: $version"
curl -L -v -O $url 2>> logfile.txt
$calculated_md5=`/sbin/md5 $file | /usr/bin/cut -f 2 -d "="`
echo $calculated_md5
done < "files.diz"
Actually I have more than just one question concerning this.
how to calculate and compare the checksums the best? i wanted to store md5 checksums in the .diz file and compare it with string comparison with "cut"ting out the string
is there a way to tell curl another filename to save to? (in my case the filename gets ugly libpng-1.2.42.tar.bz2?use_mirror=biznetnetworks)
i seem to have issues with the backticks that should direct the output of the piped md5 and cut into the variable $calculated_md5. is the syntax wrong?
Thanks!
The following is a practical one-liner:
curl -s -L <url> | tee <destination-file> |
sha256sum -c <(echo "a748a107dd0c6146e7f8a40f9d0fde29e19b3e8234d2de7e522a1fea15048e70 -") ||
rm -f <destination-file>
wrapping it up in a function taking 3 arguments:
- the url
- the destination
- the sha256
download() {
curl -s -L $1 | tee $2 | sha256sum -c <(echo "$3 -") || rm -f $2
}
while IFS=: read app version file url md5
do
echo "Downloading $app Version: $version"
#use -o for output file. define $outputfile yourself
curl -L -v $url -o $outputfile 2>> logfile.txt
# use $(..) instead of backticks.
calculated_md5=$(/sbin/md5 "$file" | /usr/bin/cut -f 2 -d "=")
# compare md5
case "$calculated_md5" in
"$md5" )
echo "md5 ok"
echo "do something else here";;
esac
done < "files.diz"
My curl has a -o (--output) option to specify an output file. There's also a problem with your assignment to $calculated_md5. It shouldn't have the dollar sign at the front when you assign to it. I don't have /sbin/md5 here so I can't comment on that. What I do have is md5sum. If you have it too, you might consider it as an alternative. In particular, it has a --check option that works from a file listing of md5sums that might be handy for your situation. HTH.

Resources