0

I am a beginner in shell scripting. I am trying to write a shell script which reads a file and prints out the lines in the file that starts with and ends with a certain word - say "Hi" in my case.. So I wrote he script to find the lines which starts with "Hi" , but got an error..Any help what is the problem?

    f="\bkg\inp.txt"
    while IFS='' read -r line || [[ -n "$line" ]]; do

        if [[ $line=="Hi*"]]; then
            printf '%s\n' "$line"
        fi

    done < "$f"

The error says:

$ sh script.sh
script.sh: line 5: unexpected token `;', conditional binary operator expected
script.sh: line 5: syntax error near `;'
script.sh: line 5: `    if [[ $line=="Hi*"]]; then'

Any help is very much appreciated ..

user9185187
  • 52
  • 2
  • 11
  • 4
    Why don't you use a simple `grep`? – Poshi Feb 15 '19 at 19:49
  • 3
    Spaces around `==` but this is job of `grep` – anubhava Feb 15 '19 at 19:49
  • and whats the process of determining strings that end with a certain word? – user9185187 Feb 15 '19 at 19:52
  • 5
    Add a shebang and then paste your script there: http://www.shellcheck.net/ – Cyrus Feb 15 '19 at 19:57
  • 2
    As per @Cyrus's suggestion, whenever you have a shell script error, a good first step is to cut and paste your code into [shellcheck.net](http://www.shellcheck.net/) and correct the errors (important) and warnings (might be important) that it identifies. If you have trouble understanding its messages, then come here and ask. – John1024 Feb 15 '19 at 20:28
  • See [Why should there be a space after open square bracketsand before close square bracket in Bash?](https://stackoverflow.com/q/9581064/4154375) and [Why equal to operator does not work if it is not surrounded by space?](https://stackoverflow.com/q/4977367/4154375). – pjh Feb 15 '19 at 20:36
  • 2
    Using `sh` to run a `bash` script is also an error; see [Difference between `sh` and `bash`](https://stackoverflow.com/questions/5725296/difference-between-sh-and-bash) – tripleee Feb 15 '19 at 20:38
  • 1
    Ok I got it, thanks @John1024 – user9185187 Feb 15 '19 at 20:39

2 Answers2

2

Simply use grep..like @Poshi and @anubhava said..

No need to use such structure...

  1. For detecting the lines that start with a string :

    grep "^strt" f.txt
    
  2. Matching the lines that end with a string:

    grep "endstr$" f.txt
    
Cyrus
  • 84,225
  • 14
  • 89
  • 153
Achy97
  • 994
  • 1
  • 14
  • 29
1
    if [[ $line=="Hi*"]]; then
  1. Between if and then, you provide a list of commands. [[ is a command, it is not mere syntax. For quick documentations, at a bash prompt, enter help if and help [[.
  2. The shell relies on whitespace to separate commands from arguments. For example, you have to type cd some_directory, not cdsome_directory
  3. The [[ command requires ]] to be the last argument. This is the source of the error: the closing double brackets as a stand-alone argument were not seen before the semicolon.
  4. The [[ command behaves differently depending on how many arguments it receives. For example, when given a single argument, [[ will return "success" if that argument is a non-empty string. So you will get different results when $line does not start with "Hi":

    line=foo
    [[ $line=="Hi"* ]]   && echo Y || echo N     # prints Y
    [[ $line == "Hi"* ]] && echo Y || echo N     # prints N
    
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • Thanks for this..very helpful – user9185187 Feb 15 '19 at 20:30
  • It's useful to get suggestions for better ways to solve your problem, but understanding why the errors occur is very important. – glenn jackman Feb 15 '19 at 20:33
  • And for a beginner shell scripter, it's pretty impressive. Do you understand why you need `IFS=''` and `-r` and `|| [[ -n $line ]]` ? – glenn jackman Feb 15 '19 at 20:34
  • Hi sir, I wont be lying..I had to take the code from stackoverflow.. – user9185187 Feb 15 '19 at 20:42
  • Nothing to be ashamed about. Just try to understand all the parts, and how `while IFS= read -r line || [[ -n $line ]]` is different from `while read line` – glenn jackman Feb 15 '19 at 20:46
  • but as far I understood IFS=' ' is for -"not trimming whitespace".. -r is to stop interpreting backslashes and the later part is to not ignore the last linne of the file which might not have a "\n" – user9185187 Feb 15 '19 at 20:46
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/188499/discussion-between-user9185187-and-glenn-jackman). – user9185187 Feb 15 '19 at 20:47