Bash file to variable string problem -- must be simple. What am I missing?

classic Classic list List threaded Threaded
16 messages Options
Reply | Threaded
Open this post in threaded view
|

Bash file to variable string problem -- must be simple. What am I missing?

deb-12


This has to be simple and I'm just missing it.

If I pull a filename from a temp file into a variable, I can ls it fine.

If I cut off the extension, and tack on my own SAME EXT, ls no longer works.

(The actual script is more elaborate, loading vlc , etc -- but this summarizes & shows my issue)


# mp4file.txt holds just 'long file with spaces.mp4'


fname=$(<mp4file.txt)

# echo $fname shows the right filename.mp4 string

# works
ls -al "$fname"


# Cut off the extension.
fname=`echo $fname | rev | cut -d. -f2 | rev`

# echo $fname shows the filename sans '.mp4'


# THIS LS FAILS, WITH FILE NOT FOUND (but actually reports the exact string that worked above, but not being found here).

ls -al "$fname".mp4

ls: cannot access 'long file with spaces.mp4': No such file or directory

------------------------------------------------------


It is not:

* a special character thing,

* a carriage return thing,

* a character case thing,

* not helped with './' or '~/' added in front of the filename.

* It's the same string in both spots.


Any thoughts folks?

Thanks





Reply | Threaded
Open this post in threaded view
|

Re: Bash file to variable string problem -- must be simple. What am I missing?

Roberto C. Sánchez-2
On Sat, Mar 02, 2019 at 07:56:58PM -0500, deb wrote:

>    This has to be simple and I'm just missing it.
>
>    If I pull a filename from a temp file into a variable, I can ls it fine.
>
>    If I cut off the extension, and tack on my own SAME EXT, ls no longer
>    works.
>
>    (The actual script is more elaborate, loading vlc , etc -- but this
>    summarizes & shows my issue)
>
>    # mp4file.txt holds just 'long file with spaces.mp4'
>
>    fname=$(<mp4file.txt)
>
>    # echo $fname shows the right filename.mp4 string
>
>    # works
>    ls -al "$fname"
>
>    # Cut off the extension.
>    fname=`echo $fname | rev | cut -d. -f2 | rev`
>
>    # echo $fname shows the filename sans '.mp4'
>
>    # THIS LS FAILS, WITH FILE NOT FOUND (but actually reports the exact
>    string that worked above, but not being found here).
>
>    ls -al "$fname".mp4
>
>    ls: cannot access 'long file with spaces.mp4': No such file or directory
>
I cannot replicate the behavior you describe.  Here is how it looks for
me:

root@chroot:~# touch "long file with spaces.mp4"
root@chroot:~# echo "long file with spaces.mp4" >mp4file.txt
root@chroot:~# cat mp4file.txt
long file with spaces.mp4
root@chroot:~# ls -l
total 4
-rw-r--r-- 1 root root  0 Mar  3 01:02 long file with spaces.mp4
-rw-r--r-- 1 root root 26 Mar  3 01:02 mp4file.txt
root@chroot:~# fname=$(<mp4file.txt)
root@chroot:~# ls -al "$fname"
-rw-r--r-- 1 root root 0 Mar  3 01:02 long file with spaces.mp4
root@chroot:~# fname=`echo $fname | rev | cut -d. -f2 | rev`
root@chroot:~# ls -al "$fname".mp4
-rw-r--r-- 1 root root 0 Mar  3 01:02 long file with spaces.mp4

What version of bash are you using?

>    ------------------------------------------------------
>
>    It is not:
>
>    * a special character thing,
>
>    * a carriage return thing,
>
>    * a character case thing,
>
>    * not helped with './' or '~/' added in front of the filename.
>
>    * It's the same string in both spots.
>
>    Any thoughts folks?
>
I am not sure about the overall problem, but I can say I would replace
this:

fname=`echo $fname | rev | cut -d. -f2 | rev`

with this:

fname=$(basename "$fname" .mp4)

Regards,

-Roberto

--
Roberto C. Sánchez

Reply | Threaded
Open this post in threaded view
|

re: Bash file to variable string problem -- must be simple. What am I missing?

deb-12


On 3/2/19 8:07 PM, Roberto C. Sánchez wrote:
On Sat, Mar 02, 2019 at 07:56:58PM -0500, deb wrote:
   This has to be simple and I'm just missing it.

   If I pull a filename from a temp file into a variable, I can ls it fine.

   If I cut off the extension, and tack on my own SAME EXT, ls no longer
   works.

   (The actual script is more elaborate, loading vlc , etc -- but this
   summarizes & shows my issue)

   # mp4file.txt holds just 'long file with spaces.mp4'

   fname=$(<mp4file.txt)

   # echo $fname shows the right filename.mp4 string

   # works
   ls -al "$fname"

   # Cut off the extension.
   fname=`echo $fname | rev | cut -d. -f2 | rev`

   # echo $fname shows the filename sans '.mp4'

   # THIS LS FAILS, WITH FILE NOT FOUND (but actually reports the exact
   string that worked above, but not being found here).

   ls -al "$fname".mp4

   ls: cannot access 'long file with spaces.mp4': No such file or directory

I cannot replicate the behavior you describe.  Here is how it looks for
me:

root@chroot:~# touch "long file with spaces.mp4"
root@chroot:~# echo "long file with spaces.mp4" >mp4file.txt
root@chroot:~# cat mp4file.txt 
long file with spaces.mp4
root@chroot:~# ls -l
total 4
-rw-r--r-- 1 root root  0 Mar  3 01:02 long file with spaces.mp4
-rw-r--r-- 1 root root 26 Mar  3 01:02 mp4file.txt
root@chroot:~# fname=$(<mp4file.txt)
root@chroot:~# ls -al "$fname"
-rw-r--r-- 1 root root 0 Mar  3 01:02 long file with spaces.mp4
root@chroot:~# fname=`echo $fname | rev | cut -d. -f2 | rev`
root@chroot:~# ls -al "$fname".mp4
-rw-r--r-- 1 root root 0 Mar  3 01:02 long file with spaces.mp4

What version of bash are you using?

   ------------------------------------------------------

   It is not:

   * a special character thing,

   * a carriage return thing,

   * a character case thing,

   * not helped with './' or '~/' added in front of the filename.

   * It's the same string in both spots.

   Any thoughts folks?

I am not sure about the overall problem, but I can say I would replace
this:

fname=`echo $fname | rev | cut -d. -f2 | rev`

with this:

fname=$(basename "$fname" .mp4)

Regards,

-Roberto


Thank you Roberto.


# Cut off the extension.
# fname=`echo $fname | rev | cut -d. -f2 | rev`

fname=$(basename "$fname" .mp4)

^ this does work for the ls, but I do not know that it will be a .mp4.


(It could be a .mkv, .webm, .ogg, .mp4, etc.)

What is certain is the filename to  the left of the final '.'.

So I was building up the different choices to file test for, hence the fname=`echo $fname | rev | cut -d. -f2 | rev`




I'm running:

cat /etc/issue
9.8

bash --version
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)








Reply | Threaded
Open this post in threaded view
|

re: Bash file to variable string problem -- must be simple. What am I missing?

der.hans
Am 02. Mar, 2019 schwätzte deb so:

moin moin,

rather than the double-reverse, try the truncate operator.

basename=${fname%.*}

$ ( fname=fred.mp4; echo ${fname%.*} )
fred
$ ( fname=fred.georg.mp4; echo ${fname%.*} )
fred.georg
$ ( fname=fred.txt; echo ${fname%.*} )
fred
$ ( fname=fred; echo ${fname%.*} )
fred
$

'%' says to look for the named pattern at the end of the value.

In this case '.*' says the last dot and everything after it if there is a
period in the value.

'%' is not greedy, so will match as little as possible, use '%%' to get
greedy if you need it.

ciao,

der.hans


> On 3/2/19 8:07 PM, Roberto C. Sánchez wrote:
>> On Sat, Mar 02, 2019 at 07:56:58PM -0500, deb wrote:
>>>     This has to be simple and I'm just missing it.
>>>
>>>     If I pull a filename from a temp file into a variable, I can ls it
>>> fine.
>>>
>>>     If I cut off the extension, and tack on my own SAME EXT, ls no longer
>>>     works.
>>>
>>>     (The actual script is more elaborate, loading vlc , etc -- but this
>>>     summarizes & shows my issue)
>>>
>>>     # mp4file.txt holds just 'long file with spaces.mp4'
>>>
>>>     fname=$(<mp4file.txt)
>>>
>>>     # echo $fname shows the right filename.mp4 string
>>>
>>>     # works
>>>     ls -al "$fname"
>>>
>>>     # Cut off the extension.
>>>     fname=`echo $fname | rev | cut -d. -f2 | rev`
>>>
>>>     # echo $fname shows the filename sans '.mp4'
>>>
>>>     # THIS LS FAILS, WITH FILE NOT FOUND (but actually reports the exact
>>>     string that worked above, but not being found here).
>>>
>>>     ls -al "$fname".mp4
>>>
>>>     ls: cannot access 'long file with spaces.mp4': No such file or
>>> directory
>>>
>> I cannot replicate the behavior you describe.  Here is how it looks for
>> me:
>>
>> root@chroot:~# touch "long file with spaces.mp4"
>> root@chroot:~# echo "long file with spaces.mp4" >mp4file.txt
>> root@chroot:~# cat mp4file.txt
>> long file with spaces.mp4
>> root@chroot:~# ls -l
>> total 4
>> -rw-r--r-- 1 root root  0 Mar  3 01:02 long file with spaces.mp4
>> -rw-r--r-- 1 root root 26 Mar  3 01:02 mp4file.txt
>> root@chroot:~# fname=$(<mp4file.txt)
>> root@chroot:~# ls -al "$fname"
>> -rw-r--r-- 1 root root 0 Mar  3 01:02 long file with spaces.mp4
>> root@chroot:~# fname=`echo $fname | rev | cut -d. -f2 | rev`
>> root@chroot:~# ls -al "$fname".mp4
>> -rw-r--r-- 1 root root 0 Mar  3 01:02 long file with spaces.mp4
>>
>> What version of bash are you using?
>>
>>>     ------------------------------------------------------
>>>
>>>     It is not:
>>>
>>>     * a special character thing,
>>>
>>>     * a carriage return thing,
>>>
>>>     * a character case thing,
>>>
>>>     * not helped with './' or '~/' added in front of the filename.
>>>
>>>     * It's the same string in both spots.
>>>
>>>     Any thoughts folks?
>>>
>> I am not sure about the overall problem, but I can say I would replace
>> this:
>>
>> fname=`echo $fname | rev | cut -d. -f2 | rev`
>>
>> with this:
>>
>> fname=$(basename "$fname" .mp4)
>>
>> Regards,
>>
>> -Roberto
>>
> *
> *
>
> *Thank you Roberto.*
>
>
> # Cut off the extension.
> # fname=`echo $fname | rev | cut -d. -f2 | rev`
>
> fname=$(basename "$fname" .mp4)
>
> ^ this does work for the *ls*, but I do not know that it will be a .mp4.
>
>
> (It could be a .mkv, .webm, .ogg, .mp4, etc.)
>
> What is certain is the filename to  the left of the final '.'.
>
> So I was building up the different choices to file test for, hence the
> fname=`echo $fname | rev | cut -d. -f2 | rev`
>
>
>
>
> I'm running:
>
> cat /etc/issue
> 9.8
>
> bash --version
> GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
>
>
>
>
>
>
>
>
>
--
#  https://www.LuftHans.com   https://www.PhxLinux.org
#  Intelligence without compassion is a waste.  -- der.hans
Reply | Threaded
Open this post in threaded view
|

Re: Bash file to variable string problem -- must be simple. What am I missing?

David Wright-3
In reply to this post by deb-12
On Sat 02 Mar 2019 at 21:48:26 (-0500), deb wrote:

> On 3/2/19 8:07 PM, Roberto C. Sánchez wrote:
> > On Sat, Mar 02, 2019 at 07:56:58PM -0500, deb wrote:
> > >     This has to be simple and I'm just missing it.
> > >
> > >     If I pull a filename from a temp file into a variable, I can ls it fine.
> > >
> > >     If I cut off the extension, and tack on my own SAME EXT, ls no longer
> > >     works.
> > >
> > >     (The actual script is more elaborate, loading vlc , etc -- but this
> > >     summarizes & shows my issue)
> > >
> > >     # mp4file.txt holds just 'long file with spaces.mp4'
> > >
> > >     fname=$(<mp4file.txt)
> > >
> > >     # echo $fname shows the right filename.mp4 string
> > >
> > >     # works
> > >     ls -al "$fname"
> > >
> > >     # Cut off the extension.
> > >     fname=`echo $fname | rev | cut -d. -f2 | rev`
> > >
> > >     # echo $fname shows the filename sans '.mp4'
> > >
> > >     # THIS LS FAILS, WITH FILE NOT FOUND (but actually reports the exact
> > >     string that worked above, but not being found here).
> > >
> > >     ls -al "$fname".mp4
> > >
> > >     ls: cannot access 'long file with spaces.mp4': No such file or directory
> > >
> > I cannot replicate the behavior you describe.  Here is how it looks for
> > me:
> >
> > root@chroot:~# touch "long file with spaces.mp4"
> > root@chroot:~# echo "long file with spaces.mp4" >mp4file.txt
> > root@chroot:~# cat mp4file.txt
> > long file with spaces.mp4
> > root@chroot:~# ls -l
> > total 4
> > -rw-r--r-- 1 root root  0 Mar  3 01:02 long file with spaces.mp4
> > -rw-r--r-- 1 root root 26 Mar  3 01:02 mp4file.txt
> > root@chroot:~# fname=$(<mp4file.txt)
> > root@chroot:~# ls -al "$fname"
> > -rw-r--r-- 1 root root 0 Mar  3 01:02 long file with spaces.mp4
> > root@chroot:~# fname=`echo $fname | rev | cut -d. -f2 | rev`
> > root@chroot:~# ls -al "$fname".mp4
> > -rw-r--r-- 1 root root 0 Mar  3 01:02 long file with spaces.mp4
> >
> > What version of bash are you using?
> >
> > >     ------------------------------------------------------
> > >
> > >     It is not:
> > >
> > >     * a special character thing,
> > >
> > >     * a carriage return thing,
> > >
> > >     * a character case thing,
> > >
> > >     * not helped with './' or '~/' added in front of the filename.
> > >
> > >     * It's the same string in both spots.
> > >
> > >     Any thoughts folks?
> > >
> > I am not sure about the overall problem, but I can say I would replace
> > this:
> >
> > fname=`echo $fname | rev | cut -d. -f2 | rev`
> >
> > with this:
> >
> > fname=$(basename "$fname" .mp4)
> >
> > Regards,
> >
> > -Roberto
> >
> *
> *
>
> *Thank you Roberto.*
>
>
> # Cut off the extension.
> # fname=`echo $fname | rev | cut -d. -f2 | rev`
>
> fname=$(basename "$fname" .mp4)
>
> ^ this does work for the *ls*, but I do not know that it will be a .mp4.
>
>
> (It could be a .mkv, .webm, .ogg, .mp4, etc.)
>
> What is certain is the filename to  the left of the final '.'.
>
> So I was building up the different choices to file test for, hence the
> fname=`echo $fname | rev | cut -d. -f2 | rev`
>
> I'm running:
>
> cat /etc/issue
> 9.8
>
> bash --version
> GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)

Let's see:

wren!david 22:48:49 /tmp $ fname=$(<mp4file.txt)
wren!david 22:48:59 /tmp $ ls -la "$fname"
-rw-r----- 1 david david 0 Mar  2 22:48  long file with spaces.mp4
wren!david 22:49:10 /tmp $ fname=`echo $fname | rev | cut -d. -f2 | rev`
wren!david 22:49:23 /tmp $ ls -la "$fname".mp4
ls: cannot access 'long file with spaces.mp4': No such file or directory
2 wren!david 22:49:35 /tmp $

Here are the preceding two lines:

wren!david 22:48:23 /tmp $ touch ' long file with spaces.mp4'
wren!david 22:48:25 /tmp $ echo ' long file with spaces.mp4' > mp4file.txt

I notice that you haven't actually pasted your own session in the OP,
so we don't really know what strings you were manipulating.

Cheers,
David.

Reply | Threaded
Open this post in threaded view
|

Re: Bash file to variable string problem -- must be simple. What am I missing?

Thomas Schmitt
Hi,

if spaces are involved, then quotation marks hould be put around the
argument of "echo".

Using the leading blank from David Wright's post:

  $ fname=" long file with spaces.mp4"
  $ x=`echo $fname | rev | cut -d. -f2 | rev`
  $ test "$x".mp4 = "$fname" && echo IS EQUAL
  $

I.e. "$x".mp4 and "$fname" are not equal.
That's because the leading blank got lost in the "echo" run:

  $ echo "'$x'"
  'long file with spaces'

Now with quotation marks around $fname to preserve the leading blank:

  $ x=`echo "$fname" | rev | cut -d. -f2 | rev`
  $ test "$x".mp4 = "$fname" && echo IS EQUAL
  IS EQUAL

A similar effect would happen with double blanks inside the name:

  $ fname="long file with  double  spaces.mp4"
  $ x=`echo $fname | rev | cut -d. -f2 | rev`
  $ echo "'$x'"
  'long file with double spaces'
  $ x=`echo "$fname" | rev | cut -d. -f2 | rev`
  $ echo "'$x'"
  'long file with  double  spaces'


Have a nice day :)

Thomas

Reply | Threaded
Open this post in threaded view
|

[SOLVED] Re: Bash file to variable string problem -- must be simple. What am I missing?

deb-12
In reply to this post by der.hans


On 3/2/19 10:22 PM, der.hans wrote:
Am 02. Mar, 2019 schwätzte deb so:

moin moin,

rather than the double-reverse, try the truncate operator.

basename=${fname%.*}

$ ( fname=fred.mp4; echo ${fname%.*} )
fred
$ ( fname=fred.georg.mp4; echo ${fname%.*} )
fred.georg
$ ( fname=fred.txt; echo ${fname%.*} )
fred
$ ( fname=fred; echo ${fname%.*} )
fred
$

'%' says to look for the named pattern at the end of the value.

In this case '.*' says the last dot and everything after it if there is a
period in the value.

'%' is not greedy, so will match as little as possible, use '%%' to get
greedy if you need it.

ciao,

der.hans


On 3/2/19 8:07 PM, Roberto C. Sánchez wrote:
On Sat, Mar 02, 2019 at 07:56:58PM -0500, deb wrote:
    This has to be simple and I'm just missing it.

    If I pull a filename from a temp file into a variable, I can ls it fine.

    If I cut off the extension, and tack on my own SAME EXT, ls no longer
    works.

    (The actual script is more elaborate, loading vlc , etc -- but this
    summarizes & shows my issue)

    # mp4file.txt holds just 'long file with spaces.mp4'

    fname=$(<mp4file.txt)

    # echo $fname shows the right filename.mp4 string

    # works
    ls -al "$fname"

    # Cut off the extension.
    fname=`echo $fname | rev | cut -d. -f2 | rev`

    # echo $fname shows the filename sans '.mp4'

    # THIS LS FAILS, WITH FILE NOT FOUND (but actually reports the exact
    string that worked above, but not being found here).

    ls -al "$fname".mp4

    ls: cannot access 'long file with spaces.mp4': No such file or directory

I cannot replicate the behavior you describe.  Here is how it looks for
me:

root@chroot:~# touch "long file with spaces.mp4"
root@chroot:~# echo "long file with spaces.mp4" >mp4file.txt
root@chroot:~# cat mp4file.txt
long file with spaces.mp4
root@chroot:~# ls -l
total 4
-rw-r--r-- 1 root root  0 Mar  3 01:02 long file with spaces.mp4
-rw-r--r-- 1 root root 26 Mar  3 01:02 mp4file.txt
root@chroot:~# fname=$(<mp4file.txt)
root@chroot:~# ls -al "$fname"
-rw-r--r-- 1 root root 0 Mar  3 01:02 long file with spaces.mp4
root@chroot:~# fname=`echo $fname | rev | cut -d. -f2 | rev`
root@chroot:~# ls -al "$fname".mp4
-rw-r--r-- 1 root root 0 Mar  3 01:02 long file with spaces.mp4

What version of bash are you using?

    ------------------------------------------------------

    It is not:

    * a special character thing,

    * a carriage return thing,

    * a character case thing,

    * not helped with './' or '~/' added in front of the filename.

    * It's the same string in both spots.

    Any thoughts folks?

I am not sure about the overall problem, but I can say I would replace
this:

fname=`echo $fname | rev | cut -d. -f2 | rev`

with this:

fname=$(basename "$fname" .mp4)

Regards,

-Roberto

*
*

*Thank you Roberto.*


# Cut off the extension.
# fname=`echo $fname | rev | cut -d. -f2 | rev`

fname=$(basename "$fname" .mp4)

^ this does work for the *ls*, but I do not know that it will be a .mp4.


(It could be a .mkv, .webm, .ogg, .mp4, etc.)

What is certain is the filename to  the left of the final '.'.

So I was building up the different choices to file test for, hence the fname=`echo $fname | rev | cut -d. -f2 | rev`




I'm running:

cat /etc/issue
9.8

bash --version
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)





This did it!


fname=${fname%.*}


# Works perfectly

Thank you der.hans!


(I am working through these responses in delivered order -- but this was the first one to work).










Reply | Threaded
Open this post in threaded view
|

Re: Bash file to variable string problem -- must be simple. What am I missing?

David Wright-3
In reply to this post by Thomas Schmitt
On Sun 03 Mar 2019 at 08:43:28 (+0100), Thomas Schmitt wrote:

> if spaces are involved, then quotation marks hould be put around the
> argument of "echo".

Yep. But I guess we're solving Problem A, the subject line's
reported paradox (which was never actually demonstrated),
rather than Problem B, which wasn't revealed until the
OP's follow-up.

Letting the shell parse and reparse is rarely a good idea
and can lead to quoting hell, necessitating a visit to one
of Greg's wikis.

Cheers,
David.

Reply | Threaded
Open this post in threaded view
|

Re: Bash file to variable string problem -- must be simple. What am I missing?

Thomas Schmitt
Hi,

i wrote:
> > if spaces are involved, then quotation marks should be put around the
> > argument of "echo".

David Wright wrote:
> Yep. But I guess we're solving Problem A, the subject line's
> reported paradox (which was never actually demonstrated),
> rather than Problem B, which wasn't revealed until the
> OP's follow-up.

deb wrote originally:
> > > # THIS LS FAILS, WITH FILE NOT FOUND (but actually reports the exact string
> > > that worked above, but not being found here).

This is of course impossible in a deterministic world.
So either black magic, quantum logic, or non-identical strings are at work.
I bet on eye spoofing by blanks and maybe a proportional text font.


> Letting the shell parse and reparse is rarely a good idea
> and can lead to quoting hell, necessitating a visit to one
> of Greg's wikis.

I think my theory could be classified as a simplifying merger of
  https://mywiki.wooledge.org/BashPitfalls#for_f_in_.24.28ls_.2A.mp3.29
and
  https://mywiki.wooledge.org/BashPitfalls#echo_.24foo


Have a nice day :)

Thomas

Reply | Threaded
Open this post in threaded view
|

[SOLVED II] (Thomas) Re: Bash file to variable string problem -- must be simple. What am I missing?

deb-12
In reply to this post by Thomas Schmitt


On 3/3/19 2:43 AM, Thomas Schmitt wrote:
Hi,

if spaces are involved, then quotation marks hould be put around the
argument of "echo".

Using the leading blank from David Wright's post:

  $ fname=" long file with spaces.mp4"
  $ x=`echo $fname | rev | cut -d. -f2 | rev`
  $ test "$x".mp4 = "$fname" && echo IS EQUAL
  $

I.e. "$x".mp4 and "$fname" are not equal.
That's because the leading blank got lost in the "echo" run:

  $ echo "'$x'"
  'long file with spaces'

Now with quotation marks around $fname to preserve the leading blank:

  $ x=`echo "$fname" | rev | cut -d. -f2 | rev`
  $ test "$x".mp4 = "$fname" && echo IS EQUAL
  IS EQUAL

A similar effect would happen with double blanks inside the name:

  $ fname="long file with  double  spaces.mp4"
  $ x=`echo $fname | rev | cut -d. -f2 | rev`
  $ echo "'$x'"
  'long file with double spaces'
  $ x=`echo "$fname" | rev | cut -d. -f2 | rev`
  $ echo "'$x'"
  'long file with  double  spaces'


Have a nice day :)

Thomas



Good thought Thomas!

This also worked:

  $ fname=`echo "$fname" | rev | cut -d. -f2 

Now, the actual file did not have a leading (or trailing) space --- which I focused on.

But IT DID have 2 adjoining spaces Within the filename.

Enclosing $fname in "", worked perfectly.


That simple thing, that I thought I was missing, I would not have guessed at. Two adjoining spaces. :-)

Thank you!

Reply | Threaded
Open this post in threaded view
|

Re: Bash file to variable string problem -- must be simple. What am I missing?

David Wright-3
On Sun 03 Mar 2019 at 13:10:39 (-0500), deb wrote:

>
> On 3/3/19 2:43 AM, Thomas Schmitt wrote:
> > Hi,
> >
> > if spaces are involved, then quotation marks hould be put around the
> > argument of "echo".
> >
> > Using the leading blank from David Wright's post:
> >
> >    $ fname=" long file with spaces.mp4"
> >    $ x=`echo $fname | rev | cut -d. -f2 | rev`
> >    $ test "$x".mp4 = "$fname" && echo IS EQUAL
> >    $
> >
> > I.e. "$x".mp4 and "$fname" are not equal.
> > That's because the leading blank got lost in the "echo" run:
> >
> >    $ echo "'$x'"
> >    'long file with spaces'
> >
> > Now with quotation marks around $fname to preserve the leading blank:
> >
> >    $ x=`echo "$fname" | rev | cut -d. -f2 | rev`
> >    $ test "$x".mp4 = "$fname" && echo IS EQUAL
> >    IS EQUAL
> >
> > A similar effect would happen with double blanks inside the name:
> >
> >    $ fname="long file with  double  spaces.mp4"
> >    $ x=`echo $fname | rev | cut -d. -f2 | rev`
> >    $ echo "'$x'"
> >    'long file with double spaces'
> >    $ x=`echo "$fname" | rev | cut -d. -f2 | rev`
> >    $ echo "'$x'"
> >    'long file with  double  spaces'
>
> Good thought Thomas!
>
> This also worked:
>
>   $ fname=`echo "$fname" | rev | cut -d. -f2
>
> Now, the actual file did not have a leading (or trailing) space ---
> which I focused on.
>
> But IT DID have 2 adjoining spaces Within the filename.

Are you using a proportional font, by any chance, for working
on these scripts. Not a good idea.

The reason I picked on a leading space in my example was that the
eye is much more sensitive to embedded space than at the margins.
Sometimes I "lose" a file by renaming it, pasting the new name in
mc, which will preserve any accidental leading and trailing whitespace.

> Enclosing $fname in "", worked perfectly.
>
> That simple thing, that I thought I was missing, I would not have
> guessed at. Two adjoining spaces. :-)

Had the original string been pasted into the OP, like your error
message at the end, it would have been obvious to those of us using
fixed-width fonts. (BTW, asterisks are fine in the *text*, but
are no help elsewhere in the post, like in your "$fname".mp4**)

Cheers,
David.

Reply | Threaded
Open this post in threaded view
|

Re: Bash file to variable string problem -- must be simple. What am I missing?

Thomas Schmitt
In reply to this post by deb-12
Hi,

deb wrote:
> Two adjoining spaces. :-)

Really tricky are file names containing newline characters.

Your use case might already balance on the border line where a more
straightforward programming language than bash should be considered and
a fully capable file content protocol should be defined.
(Protocol candidates would be: Shell-style quotation and line continuation,
or the good old hollerith string representation.)


Have a nice day :)

Thomas

Reply | Threaded
Open this post in threaded view
|

Re: Bash file to variable string problem -- must be simple. What am I missing?

Greg Wooledge
In reply to this post by David Wright-3
On Sun, Mar 03, 2019 at 09:33:07AM -0600, David Wright wrote:
> Letting the shell parse and reparse is rarely a good idea
> and can lead to quoting hell, necessitating a visit to one
> of Greg's wikis.

For this particular thread, I recommend:

https://mywiki.wooledge.org/BashFAQ/100

Reply | Threaded
Open this post in threaded view
|

Greg: Re: Bash file to variable string problem -- must be simple. What am I missing?

deb-12

On 3/4/19 8:33 AM, Greg Wooledge wrote:
> On Sun, Mar 03, 2019 at 09:33:07AM -0600, David Wright wrote:
>> Letting the shell parse and reparse is rarely a good idea
>> and can lead to quoting hell, necessitating a visit to one
>> of Greg's wikis.
> For this particular thread, I recommend:
>
> https://mywiki.wooledge.org/BashFAQ/100
>
>

Good link Greg.

Thank you.


Reply | Threaded
Open this post in threaded view
|

David - Re: Bash file to variable string problem -- must be simple. What am I missing?

deb-12
In reply to this post by David Wright-3

On 3/3/19 2:38 PM, David Wright wrote:
> Are you using a proportional font, by any chance, for working
> on these scripts. Not a good idea.

I am not using a proportional font anywhere.


> Had the original string been pasted into the OP, like your error
> message at the end, it would have been obvious to those of us using
> fixed-width fonts.
>
> Cheers,
> David.
>
>
Interestingly -- two people got to different, correct, answers quickly,
without seeing the actual string (that you mentioned a couple of times).

Thanks



Reply | Threaded
Open this post in threaded view
|

Re: David - Re: Bash file to variable string problem -- must be simple. What am I missing?

Greg Wooledge
On Mon, Mar 04, 2019 at 08:59:37AM -0500, deb wrote:
> Interestingly -- two people got to different, correct, answers quickly,
> without seeing the actual string (that you mentioned a couple of times).

Experience.  Those who have been using the Unix command line long enough
know where the dangers are, and how to avoid them, and how to trigger
them in someone else's imperfect code.

Seeing something like

echo $fname | ...

immediately raises red flags.  For some of us, more than one red flag.

The big flag is for the unquoted variable expansion.  We know that this
can break if there are leading spaces, or trailing spaces, or multiple
back-to-back spaces, or some glob character like a * with spaces around
it, in the filename.  The vast majority of the time, if it's going to
break, it'll be because of incorrect quoting.

The smaller red flag is for echo.  This can break if the filename is,
or contains, something with special meaning to echo.  For example, if
the filename is -n then you're just totally screwed.  But also, if the
filename contains certain backslash+letter sequences, some versions of
echo will interpret those -- and some versions WON'T.  You can't even
guarantee the results.  This is FAR less likely to be a problem, but it's
still something to keep in mind.

For this particular question ("I want the filename without its extension"),
the right answers have already been given, so I won't rehash that.

If in the future there were actually some need to write the filename to
a pipe, this is the only safe way to do it:

printf %s "$fname" | ...

That doesn't add a newline (which echo does).  So if you also need to
add a newline to it, then:

printf %s\\n "$fname" | ...

There's some flexibility in the quoting for the first argument.
Some people will write '%s\n' and some will write "%s\n" or "%s\\n" --
these are acceptable alternatives.

The important thing is that you do NOT write  printf "$fname"  because
that's wrong.  If you write that, then you're back to the original
problem where some part of the filename may be interpreted by the command
you're using to write it, which is not what you want.