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.
    – user232326
    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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .