2

UPDATE Edited the script slightly for a more specific regex, still same problem.

Clarifying following questions, this is my exact script I want to get working (POC for a bigger script), test.txt is in the same directory as my test.sh file and I'm running the script cd'ed in the same directory.

Also, whilst tinkering, I think this might be related to carriage returns, but I still can't figure out what's going wrong.

END UPDATE

I've looked around here to paste together a bash file I can run to extract a version number from a specific file, and do stuff with that version number via the variable. I have the rest of the script working if I just supply the version via an argument $1, but it'd be neat if it could just determine the version number directly from the file in the folder I want to manipulate.

Here's my current script

#!/bin/sh version=$(sed -ne "s/\\Version *: *\([0-9a-zA-Z\.\-]+\)*/\1/p" test.txt) printf 'detected version %s for test.txt\n' "$version" 

Which returns me this value in terminal

 for test.txtion 0.6 

It seems to overwrite part of the string I'm trying to print. If I just take this part:

sed -ne "s/\\Version *: *\([0-9a-zA-Z\.\-]+\)*/\1/p" test.txt 

It works for example if there's a line in the file containing this line

Version: 0.6 

I get this:

root@webserver [/home/username]# sed -ne "s/\\Version *: *\([0-9a-zA-Z\.\-]+\)*/\1/p" test.txt 0.6 root@webserver [/home/username]# 

Any ideas on what's wrong for the script?

17
  • 2
    Is it possible, that the file contains carriage returns (\r) in the "Version:..." line? I think the start of your output might be overwritten by the end. Try removing for $file to see, if the version number is printed.
    – eike
    CommentedSep 12, 2019 at 11:46
  • 4
    Is that your actual code? if so, you are adding an additional suffix to the file name ($file.php when file is already assigned the value filename.php). Does the file filename.php.php exist?CommentedSep 12, 2019 at 11:50
  • 1
    You might want to use grep instead of sed ... And do not use variables in the FORMAT argument of printf. Use printf 'detected version %s for %s\n' "$version" "$file"
    – pLumo
    CommentedSep 12, 2019 at 14:19
  • @eike it's very possible, I'm going to check that out and get back to you thanks
    – marcus
    CommentedSep 12, 2019 at 19:17
  • @steeldriver This isn't exactly my code, but the $file.php part is essentially the same just different variable names. I've removed that variable now for simplicity and used hard links, the issue I have is with the sed part really.
    – marcus
    CommentedSep 12, 2019 at 19:17

1 Answer 1

1

I found the reason this wasn't working, and also the solution. As @eike commented in my OP, the issue was the carriage return \r from DOS overwriting the output. More problematically for me, the \r got added to my variable for some reason.

Removing the \r manually wasn't an option because that file gets updated regularly.

After a bit of searching, I found this to fix my problem and print out the string correctly:

#!/bin/bash version=$(sed 's/\r$//' test.txt | sed -ne "s/\\Version *: *\([0-9a-zA-Z\.\-]+\)*/\1/p") printf 'detected version %s for test.txt\n' "$version" 

What it does here is first remove the \r from the text and pass that to the regex part. and I get the expected output:

detected version 0.6 for test.txt

I'm sure there's a way to do it from within the regex, to ignore the \r, but this got the job done at least!

2
  • I still cannot get it to fail even with a file with DOS line endings. I think there is a bug in your regexp however: the + is supposed to match a literal plus sign if you are not using extended regexps; the 'match one or more instances of the previous match' is denoted \+ - assuming you are using GNU sed that is. And I'm not at all sure about what the final * is supposed to be doing: sed -ne "s/Version *: *\([0-9a-zA-Z\.\-]\+\)/\1/p" test.txt works fine for me.
    – NickD
    CommentedSep 15, 2019 at 22:30
  • I must be using GNU sed because the + doesn't work when escaped (I tried). Also, if it was a literal plus I wouldn't be getting the output I get since it did find the number (and there's no pluses in the string). I did find the last * odd, it's part of a regex example I picked up in another stack overflow thread. It's 100% the \r though, I don't know why, but the solution fixed all my problems so I am happy to leave it at that :) Thanks for your input @NickD
    – marcus
    CommentedSep 17, 2019 at 9:15

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.