0

In a Putty remote connection, I am trying to read a file line by line, cut each line by delimiter (";"), and run a command if the variables satisfy a condition. However, I get "not a valid identifier" upon reading the file.

Just some simple logic in the test.sh file:

while read download.archive
do
    likes = $(echo cut -d ";" -f 1 $line)
    echo $likes
    dislikes = $(echo cut -d ";" -f 2 $line)
    dislikes = $((dislikes * 95))
    url = $(echo cut -d ";" -f 3 $line)

if [$likes -gt $dislikes]
then
    youtube-dl --config-location youtube-dl-3.conf url
fi

done < download.archive

The download.archive file reads as follows-

9873;354;https://www.youtube.com/watch?v=0fd56CGnVRU
3267;54;https://www.youtube.com/watch?v=Mq4jAwPdCMw
25411;871;https://www.youtube.com/watch?v=PcSBOUpgngM
2829;44;https://www.youtube.com/watch?v=S-rj8m7Ssow
921;303;https://www.youtube.com/watch?v=JchVQMuxRVA
2014;32;https://www.youtube.com/watch?v=H8Y_ZfNViPU

Yet when I try to run ./test.sh, I get "./test.sh: line 4: read: 'download.archive': not a valid identifier". If the file is valid, why is it throwing an error?

Elie
  • 23
  • That's completely broken, but for your 1st problem: read download.archive will not work because you can't use . in variable names. Try awk -F';' '$1 > $2 {system("youtube-dl --config-location youtube-dl-3.conf "$3)}' download.archive. –  Mar 16 '20 at 17:06
  • @ctrl-alt-delor that's exactly what you get for read foo.bar: not a valid identifier. –  Mar 16 '20 at 17:07
  • @ctrl-alt-delor Sure, for ./test.sh I get "./test.sh: line 4: read:download.archive': not a valid identifier"` – Elie Mar 16 '20 at 17:08
  • @mosvy But I'm trying to read a file, not a variable...? So how would I refer to the file without using its extension? – Elie Mar 16 '20 at 17:09
  • 3
    You have to use while read line instead of while read download.archive. There are more errors in your script. Use https://www.shellcheck.net/ to find errors. – Bodo Mar 16 '20 at 17:10
  • @ctrl-alt-delor It is test.sh, condition.sh was a typo - my bad. – Elie Mar 16 '20 at 17:12
  • Please fix, and post real code, not a paraphrase of it. – ctrl-alt-delor Mar 16 '20 at 17:13
  • @Bodo Thanks Bodo for the resource. However, shellcheck.net doesn't show any error on the "while read" segment... – Elie Mar 16 '20 at 17:13
  • @Elie Unfortunately shellcheck.net doesn't show that download.archive is an invalid variable name, but it shows lots of other problems. Fix all errors. Try to explain to yourself or to us what every line of your script is intended to do. For example what do you expect while read download.archive to do or likes = $(echo cut -d ";" -f 1 $line)? – Bodo Mar 16 '20 at 17:25
  • If you try while read download.archive; do echo $line; done as an MWE i think you will spot the booboo easily enough. – bu5hman Mar 16 '20 at 17:28
  • @Bodo Thanks - I've solved it and explained the errors up above. Is there anything you would add/clarify to it? – Elie Mar 16 '20 at 17:49
  • 1
    Answers to questions should go in the answer box at the bottom of the page. It's fine to answer your own question. If you (after the short delay) accept your own answer (by clicking the greyed-out tick mark by the answer), the question will be marked as resolved. Do not put your solution in the question. – Kusalananda Mar 16 '20 at 17:51

1 Answers1

1

After numerous errors, here is the working code:

while IFS= read -r line; do

    likes=$(cut -d ";" -f 1 <<< "$line")
    dislikes=$(cut -d ";" -f 2 <<< "$line")
    likes=$((likes / 50))
    url=$(cut -d ";" -f 3 <<< "$line")

if [ $likes -gt $dislikes ]
then
    youtube-dl --config-location youtube-dl-3.conf $url
fi

done < download.archive

The "read" command's first line is always like the above (read line), and the file to be read is after the "done" statement at the end (done < download.archive). This post here explains the IFS and -r additions, and what they do.

When assigning variable, I guess you can't put a space between the assignment. As such, this doesn't work

likes = $(cut -d ";" -f 1 $line)

But this does:

likes=$(cut -d ";" -f 1 $line)

...Except, to refer to the line the program is currently reading, we must use <<<. Like this:

likes=$(cut -d ";" -f 1 <<< $line)

Lastly, when checking for a condition (in the if statement), there needs to be a space between both the beginning and ending brackets, and the condition inside, like so -

if [ $likes -gt $dislikes ]

To refer to the variable url that holds our url for youtube-dl, we refer to variables using a $. Like this:

$url

Elie
  • 23