0

I have a file which should have specific character/string at the end of each line except the last line. How to achieve this by shell script that it searches that character/string at the end of each line and add that character/string if not present?

For example, the file contents like:

hello1
hello
hell1
hel
end

it should have the character 1 at the end of each line except the last line and the output of our script should be like:

hello1
hello1
hell1
hel1
end

I think it can be written using sed or awk but I am not sure how do they works. Thanks in advance.

1
  • 2
    Should the character be removed from the last line if it found at the end of that line?
    – Kusalananda
    Oct 1, 2020 at 5:57

4 Answers 4

2

One way can be

 sed -e '
    s/1$/&/;t
    $!s/$/1/
' file 
sed -e '
  $q; /1$/!s/$/1/
' file

Or:

sed -e '$!{/1$/!s/$/1;}'

Or if there are no empty lines:

sed -e '$!s/[^1]$/&1/' 
2

Another alternative:

sed '$!s/1\{0,1\}$/1/'

(some sed implementations support the non-standard \? as an alternative to \{0,1\}).

Or its extended regexp equivalent for those sed implementations that support -E (soon to be standard):

sed -E '$!s/1?$/1/'

That is, on all lines except (!) the last ($), replace one optional (\{0,1\}/?) trailing ($) 1 with 1.

2

Using any awk in any shell on every Unix box:

$ awk 'NR>1{print p 1} {sub(/1$/,""); p=$0} END{print p}' file
hello1
hello1
hell1
hel1
end
0

You can (in sed):

  1. Remove all 1 where they exist. s/^\(.*\)1$/\1/
  2. Then add it back for all lines. s/.*/&1/
  3. But only for lines that are not the last one $!{…}
sed '$!{s/^\(.*\)1$/\1/;s/.*/&1/}' file

Or, without capturing anything (no asterisks), one of the two:

sed '$!{s/1$//;s/$/1/}' file
sed '/1$/b;$!s/$/1/' file
3
  • Dear @Isaac thanks for your prompt response. I am getting the following error: sed: -e expression #1, char 16: invalid reference \1 on `s' command's RHS
    – Tasbir
    Oct 1, 2020 at 4:39
  • Please try again, this website failed to preserve the code. Now correctly formatted.
    – done
    Oct 1, 2020 at 5:24
  • Note that sed '/1$/b;$!s/$/1/' is GNU-specific. POSIXly: sed -e '/1$/b' -e '$!s/$/1/'. Actually, they're all GNU specific, as you also need } to be delimited from the previous commands (with ; or newline or a separate -e) portably. Oct 1, 2020 at 6:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.