52

I want to put each line within quotation marks, such as:

abcdefg
hijklmn
opqrst

convert to:

"abcdefg"
"hijklmn"
"opqrst"

How to do this in Bash shell script?

anubhava
  • 761,203
  • 64
  • 569
  • 643
Bing.Physics
  • 731
  • 2
  • 6
  • 6
  • 1
    Welcome to Stack Overflow. Please read the [FAQ] soon. Your question isn't bad but it is ambiguous, or maybe just a bit incomplete. Where are the lines coming from -- from a file, or an array of variables, or lines in a single variable (or somewhere else)? Where does the output need to go? Into a variable, an array, a file, somewhere else? The answers so far show a variety of possiblilities (and don't cover all the scenarios I mention). – Jonathan Leffler Jun 07 '13 at 21:20
  • Also, an awful lot of people seem to want to do this for the wrong reasons. If you have a program which requires its arguments to be in quotes, like `./tool "example sentence one" "example sentence two"`, the quotes are consumed by the shell, and not part of the data itself. If you have those values in variables, the variables should not contain the quotes, but you need to quote the interpolation; `./tool "$sentence1" "$sentence2"` – tripleee Jun 20 '16 at 04:30

8 Answers8

52

Using awk

awk '{ print "\""$0"\""}' inputfile

Using pure bash

while read FOO; do
   echo -e "\"$FOO\""
done < inputfile

where inputfile would be a file containing the lines without quotes.

If your file has empty lines, awk is definitely the way to go:

awk 'NF { print "\""$0"\""}' inputfile

NF tells awk to only execute the print command when the Number of Fields is more than zero (line is not empty).

blue
  • 2,683
  • 19
  • 29
  • 1
    for the `read` solution, you need `IFS= read -r FOO`. Otherwise you'll lose whitespace at the beginning of lines and backslash-escapes my be lost – glenn jackman Jun 07 '13 at 19:24
  • Or lose the `FOO` and use the implicit `$REPLY` name. Just do `while read; do printf '"%s"\n' "$REPLY"; done < inputfile` – kojiro Jun 07 '13 at 19:28
  • all more reasons to go with `awk` as I see it :D – blue Jun 07 '13 at 19:29
  • @glennjackman sure, if you actually want to retain backslash escapes. – kojiro Jun 07 '13 at 19:38
  • `s/line is not empty/line is not blank/`. Note that the `-e` is not needed and will actually alter the content if it contains backslashes. – Stephane Chazelas Jun 07 '13 at 21:49
17

I use the following command:

xargs -I{lin} echo \"{lin}\" < your_filename

The xargs take standard input (redirected from your file) and pass one line a time to {lin} placeholder, and then execute the command at next, in this case a echo with escaped double quotes.

You can use the -i option of xargs to omit the name of the placeholder, like this:

xargs -i echo \"{}\" < your_filename

In both cases, your IFS must be at default value or with '\n' at least.

0zkr PM
  • 825
  • 9
  • 11
  • Consider also, that one might not really need to echo the thing, but one might have needed quote-marks to do other operations in the script. For me, I can run a command: script-that-lists-files-per-line.py | xargs -I{lin} sudo chmod a+r {lin} – macetw Jun 16 '17 at 13:42
  • You're right Mr. macetw, my mistake not put clear that's just an command example. – 0zkr PM Feb 21 '18 at 23:58
  • 1
    Using mingw xargs 4.4.2 on windows 10 from command prompt found >xargs -I{lin} echo "'"lin"'" worked for single quotes. – Bob Nov 08 '18 at 17:19
15

This sed should work for ignoring empty lines as well:

sed -i.bak 's/^..*$/"&"/' inFile

or

sed 's/^.\{1,\}$/"&"/' inFile
anubhava
  • 761,203
  • 64
  • 569
  • 643
11

Use sed:

sed -e 's/^\|$/"/g' file

More effort needed if the file contains empty lines.

choroba
  • 231,213
  • 25
  • 204
  • 289
3

I think the sed and awk are the best solution but if you want to use just shell here is small script for you.

#!/bin/bash

chr="\""
file="file.txt"
cp $file $file."_backup"
while read -r line
do
 echo "${chr}$line${chr}"
done <$file > newfile
mv newfile $file
grepit
  • 21,260
  • 6
  • 105
  • 81
  • it would be nice to at least provide some explanation as why you feel this is incorrect. – grepit Jun 07 '13 at 19:40
  • Other than showing how to output a literal double quotation mark, it does not address the topic of adding quotation marks to preexisting text at all. – chepner Jun 07 '13 at 19:43
  • @ chepner I have modified my comment and thanks for giving me a feedback so I can contribute more effectively. – grepit Jun 07 '13 at 19:55
3
paste -d\" /dev/null your-file /dev/null

(not the nicest looking, but probably the fastest)

Now, if the input may contain quotes, you may need to escape them with backslashes (and then escape backslashes as well) like:

sed 's/["\]/\\&/g; s/.*/"&"/' your-file
Stephane Chazelas
  • 5,859
  • 2
  • 34
  • 31
  • I appreciate this solution because it only required me to escape a single quotation mark when embedding the command where I needed to escape every one as `\\\"`. – ApproachingDarknessFish Oct 16 '20 at 04:56
0

This answer worked for me in mac terminal.

$ awk '{ printf "\"%s\",\n", $0 }' your_file_name

It should be noted that the text in double quotes and commas was printed out in terminal, the file itself was unaffected.

Lance Samaria
  • 17,576
  • 18
  • 108
  • 256
-3

I used sed with two expressions to replace start and end of line, since in my particular use case I wanted to place HTML tags around only lines that contained particular words.

So I searched for the lines containing words contained in the bla variable within the text file inputfile and replaced the beginnign with <P> and the end with </P> (well actually I did some longer HTML tagging in the real thing, but this will serve fine as example)

Similar to:

$ bla=foo
$ sed -e "/${bla}/s#^#<P>#" -e "/${bla}/s#\$#</P>#" inputfile
<P>foo</P>
bar
$
DOK
  • 35
  • 4