1

I have to ls command to get the details of certain types of files. The file name has a specific format. The first two words followed by the date on which the file was generated

e.g.:

Report_execution_032916.pdf

Report_execution_033016.pdf

Word summary can also come in place of report.

e.g.:

Summary_execution_032916.pdf

Hence in my shell script I put these line of codes

DATE=`date +%m%d%y`
Model=Report
file=`ls ${Model}_execution_*${DATE}_*.pdf`

But the value of Model always gets resolved to 'REPORT' and hence I get:

ls: cannot access REPORT_execution_*032916_*.pdf: No such file or directory

I am stuck at how the resolution of Model is happening here.

I can't reproduce the exact code here. Hence I have changed some variable names. Initially I had used the variable name type instead of Model. But Model is the on which I use in my actual code

Aparna Rajan
  • 153
  • 1
  • 3
  • 13
  • 4
    [Why you shouldn't parse the output of ls](http://mywiki.wooledge.org/ParsingLs). That being said, I don't see **why** `type` should turn to uppercase. Wait... your example filenames **don't** have a `.pdf` extension, while the `file=` line expects one...?!? – DevSolar Mar 29 '16 at 14:07
  • Are you sure what you posted is exactly what you have? The `$DATE` var shouldn't be expanded since your command is wrong (missing `$`). But your output indicates it is... – Mat Mar 29 '16 at 14:18
  • Hi,Thanks for the reply. MY output files have the .pdf extension. I have modified the question accordingly and written the precise error which was thrown. – Aparna Rajan Mar 29 '16 at 14:19
  • 3
    The code shown cannot result in the error shown, not without something else going on. Please provide a complete, minimal, reproducable example. (Ideally one that creates the expected file itself, e.g. via `touch `.) – DevSolar Mar 29 '16 at 14:21
  • @Mat I was wrong when Ipasted the code there was $ before date. I have modified the post – Aparna Rajan Mar 29 '16 at 14:24
  • @AparnaRajan "Report" is still uppercase for some reason? You could make a variable after `type` that only holds the filepath + filename - just to separate things while you debug – jDo Mar 29 '16 at 14:28
  • You don't have underscores after the dates in the file names, but you attempt to put one there in the glob pattern. Note that the glob `*` is different from a regex `*`; in globbing, `*` means zero or more of any character, and is equivalent to `.*` (more or less) in a normal regex. What is the value of `${type}` in your shell? Is it exported and read-only by any chance? (It's possible to make a variable read-only, and export it; I don't think that the read-only status is inherited by a child process, though. And attempts to modify a read-only variable trigger a warning.) – Jonathan Leffler Mar 29 '16 at 14:34
  • Basic debugging: what is the output from `bash -x yourscript.sh`? If the script contains only those three lines, do you get the claimed behaviour? What happens if you include `echo "[${type}]"` in your script after the `type=Report` line? You should see `[Report]` but is that what you see? Do you have a weird alias for `ls` somewhere? What else have you got in your script? In your `.bashrc` file? Do you have something like [`declare -u type`](https://www.gnu.org/software/bash/manual/bash.html#index-declare) somewhere in the system? – Jonathan Leffler Mar 29 '16 at 14:41
  • 2
    @JonathanLeffler I have another script which runs before this. That script has the line typeset -u Model. I think this sets the Model always to upper case. Thanks – Aparna Rajan Mar 29 '16 at 14:50
  • We won't be able to help much more until you include the output of `bash -x yourscript.sh` in the question. You're seeing unusual behaviour — it is hard to guess what is going on. – Jonathan Leffler Mar 29 '16 at 14:51
  • @AparnaRajan Your last remark makes it clear your question does _not_ provide a [mcve](http://stackoverflow.com/help/mcve). Besides, I cannot even tell which shell you are using. – Ruud Helderman Mar 29 '16 at 14:55

5 Answers5

1

You've changed your script to use Model=Report and ${Model} and you've said you have typeset -u Model in your script. The -u option to the typeset command (instead of declare — they're synonyms) means "convert the strings assigned to all upper-case".

-u When the variable is assigned a value, all lower-case characters are converted to upper-case. The lower-case attribute is disabled.

That explains the upper-case REPORT in the variable expansion. You can demonstrate by writing:

Model=Report
echo "Model=[${Model}]"

It would echo Model=[REPORT] because of the typeset -u Model.

  • Don't use the -u option if you don't want it.

You should probably fix your glob expression too:

file=$(ls ${Model}_execution_*${DATE}*.pdf)

Using $(…) instead of backticks is generally a good idea.

And, as a general point, learn how to Debug a Bash Script and always provide an MCVE (How to create a Minimal, Complete, and Verifiable Example?) so that we can see what your problem is more easily.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Thanks,It helped. And thanks for you suggestions. I am quite a beginner to stack exchange as well as unix shell scripting. I will definitely keep in mind these points. – Aparna Rajan Mar 29 '16 at 15:55
0

Some things to look at:

  • type is usually a reserved word, though it won't break your script, I suggest you to change that variable name to something else.
  • You are missing an $ before {DATE}, and you have an extra _ after it. If the date is the last part of the name, then there's no point in having an * at the end either. The file definition should be:

file=`ls ${type}_execution_*${DATE}.pdf`

Try debugging your code by parts: instead of doing an ls, do an echo of each variable, see what comes out, and trace the problem back to its origin.

As @DevSolar pointed out you may have problems parsing the output of ls.

Community
  • 1
  • 1
Enrico
  • 766
  • 8
  • 19
0

As a workaround

ls | grep `date +%m%d%y` | grep "_execution_" | grep -E 'Report|Summary'

filters the ls output afterwards.

touch 'Summary_execution_032916.pdf'
DATE=`date +%m%d%y`
Model=Summary
file=`ls ${Model}_execution_*${DATE}*.pdf`

worked just fine on

GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
serv-inc
  • 35,772
  • 9
  • 166
  • 188
0
Part of question: 
But the value of Model always gets resolved to 'REPORT' and hence I get:

This is due to the fact that in your script you have exported Model=Report

Part of question:
ls: cannot access REPORT_execution_*032916_*.pdf: No such file or directory

No such file our directory issue is due to the additional "_" and additional "*"s that you have put in your 3rd line. Remove it and the error will be gone. Though, Model will still resolve to Report

Original 3rd line :

 file=`ls ${Model}_execution_*${DATE}_*.pdf` 

Change it to

 file=`ls ${Model}_execution_${DATE}.pdf`

Above change will resolve the could not found issue.

Part of question
I am stuck at how the resolution of Model is happening here.

I am not sure what you are trying to achieve, but if you are trying to populate the file parameter with file name with anything_exection_someDate.pdf, then you can write your script as

DATE=`date +%m%d%y`
file=`ls *_execution_${DATE}.pdf`

If you echo the value of file you will get 
Report_execution_032916.pdf Summary_execution_032916.pdf
as the answer
Unit1
  • 249
  • 1
  • 9
0

There were some other scripts which were invoked before the control reaches the line of codes which I mentioned in the question. In one such script there is a code typeset -u Model This sets the value of the variable model always to uppercase which was the reason this error was thrown ls: cannot access REPORT_execution_032916_.pdf: No such file or directory

I am sorry that i couldn't provide a minimal,complete and verifiable code

Aparna Rajan
  • 153
  • 1
  • 3
  • 13