-1

I have a file which has several lines.

I wish to update the file while making sure that the last visible character of each line of the file is a single quote '. In case not, then we should add the single quote at the end of each line.

If the single quote is the last character in a line then leave it as is.

cat test.txt

fahsjhjkhkjhjhajkhjf
afasfsfsfffsfasf'
aaffa' sfff
wfafsfsaffs'
fsafsfs'afffafsasf

Expected output:

fahsjhjkhkjhjhajkhjf'
afasfsfsfffsfasf'
aaffa' sfff'
wfafsfsaffs'
fsafsfs'afffafsasf'
5
  • 2
    You were just shown how to do this on the last line of a file: sed "\$s/[^']\$/&'/" file. To do it on any line, just remove the \$ address condition. Mar 27 at 18:26
  • @steeldriver i tried tac test.txt | sed '1,/[[:graph:]]/ { /[[:graph:]]/!d; }' | tac | sed "\$s/[^']/&'/" and it does not work on the sample i provided.
    – Ashar
    Mar 27 at 18:39
  • i also tried tac test.txt | sed '1,/[[:graph:]]/ { /[[:graph:]]/!d; }' | tac | sed "\$s//'/" but i get error sed: -e expression #1, char 0: no previous regular expression
    – Ashar
    Mar 27 at 18:42
  • 4
    Why would you want to use tac? Don't treat programming as a "cargo cult" but instead take some time to try and understand the solutions you're given. It makes things so much easier...
    – roaima
    Mar 27 at 20:46
  • If you can have empty input lines that you want changes to a single ' then include that case in your example as some potential solutions would fail given that input. What should the output be if an input line ends with 2 's, e.g. would input of foo'' output foo'' or foo'?
    – Ed Morton
    Mar 28 at 0:27

5 Answers 5

2

The sed expression s/[^']$/&'/ inserts a single quote at the end of any line that ends with a character that is not a single quote.

In the shell:

sed "s/[^']$/&'/" file

Since the expression contains a single quote, I'm choosing to write the expression in double quotes instead. To make an in-place edit, use sed with its -i option if it implements this nonstandard option at all.

To also insert a single quote on empty lines, you could use an extra expression targeting empty lines specifically, or you could always insert a single quote at the end of the line and then replace any double single quotes that this results in.

I.e., either

sed -e "s/[^']$/&'/" -e "/^$/s//'/" file

or

sed -e "s/$/'/" -e "s/''$/'/" file
0
2

If matching the single quote whether it is there or not, and if present, replacing it is acceptable, then you can try this sed.

$ sed "s/\([^']*\)'\?$/\1'/" input_file
'fahsjhjkhkjhjhajkhjf'
afasfsfsfffsfasf'
aaffa' sfff'
wfafsfsaffs'
fsafsfs'afffafsasf'

This uses back referencing to capture every character up to the end of the line. If a single quote is found at the end of the line, then it is excluded/removed by placing the single quote outside of the capturing parenthesis.

Everything captured within the parenthesis is then returned with \1 with the single quote hardcoded to the end of each line.

1
  • 1
    Interesting approach. You should say more about how/why this works, and why you chose it over they’s shorter (and, arguably, more obvious) answer. … … … … … … … … … … … … … … … Please do not respond in comments; edit your answer to make it clearer and more complete. Mar 29 at 4:30
1

something like can do the work:

awk -v a=\' '{print $0 a}'  input.file

If you want to avoid double quotes on the end you can try something like:

 awk -v a=\' '{print $0 a}'  input.file|sed "s/''$/'/"
1

Please use sed as it is supposed to.

To add a ' at the end of all lines you do

sed "s/$/'/" file

To do an operation on some lines only, you use an address. The address of lines ending with ' is /'$/. You invert the address seletion by a !, so you get

sed "/'$/!s/$/'/" file

Short, functional, portable and also covering the empty-line-case.

(Beware not to have stupid history expansion active: set +H)

0

Assuming you want empty input lines to become ' in the output and input like foo'' to be output as foo':

$ sed "s/'*$/'/" file
fahsjhjkhkjhjhajkhjf'
afasfsfsfffsfasf'
aaffa' sfff'
wfafsfsaffs'
fsafsfs'afffafsasf'

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.