3

I have this file:
'dog', 'cat', 'horse', 'turtle'

I want to convert the line to:

dog
cat
horse
turtle

if I use just the comma as separator and command tr I can do:
tr -s ',' '\n' < file

with the output

'dog'
 'cat'
 'horse'
 'turtle'

But when I use ', ' as separator, this doesn't work:

tr -s '\', \'' '\n' < file

even if I use double back slash to escape the single quotes it still does not work. The only output I get in the terminal is >.

How do I correctly escape the single quotes to get the desired output?

9 Answers 9

5

Treating the input as quoted CSV, with skippable whitespace after each comma delimiter and using single quotes rather than the standard double quotes as quoting characters, we may use csvformat to reformat the data:

$ csvformat -S -q "'" -D $'\n' file
dog
cat
horse
turtle

This uses csvformat with -S to skip the initial whitespace characters after each delimiter, -q "'" to set the input quoting character to a single quote, and then -D $'\n' to set the output field delimiter to a newline character.

The file is then reformatted.

Any field using embedded newlines would be quoted in the output, as would field containing embedded double quotes be.

0
4

tr works on sets, not on strings. Each first symbol in the first set is replaced with the first symbol from the second set, second symbol from the first set with a second symbol from a second set, etc.

If second set has less symbols than the first one - all the symbols from the first set which doesn't have a proper pair is replaced with the last symbol of the second set.

You need

tr -s "\', "  '\n' < file

Each apostrophe, comma, and space is replaced with line feed, but the -s option squeeze all of them into one instance of LF.

3
  • 1
    This leaves a blank line at the beginning. Dec 20, 2021 at 15:41
  • Yes, it does. Because EACH letter from the first set is replaced with LF, and the source file has apostrophe at the beginning. The solution could be to use tr twice - remove apostrophes and then change commas to LF. Or go by way of sed.
    – White Owl
    Dec 20, 2021 at 23:15
  • 2
    Your "\', " string includes a (literal) backslash, so your command would treat backslashes in the input as word separators.  That wouldn’t be a problem for the sample input shown in this question, but it might cause trouble in some other scenario. You should use just "', " — you don’t have to escape ' when you use it in "...". Dec 26, 2021 at 8:34
3
$ awk -F"'" '{for (i=2;i<=NF;i+=2) print $i}' file
dog
cat
horse
turtle
3

With GNU grep or compatible when built with pcre support:

grep -Po "[\s,']*\K[^']*" < file

Note that it skips empty quoted strings (as in 'empty', 'like', '').

[\s,'] skips all whitespace, commas and single quotes, and then we Keep what follows: the next sequence of non-' characters.

2

Using sed

$ sed "s/\([^,]*\), /\1\n/g;s/'//g" input_file
dog
cat
horse
turtle
2
$ awk '!(NR%2)' RS=\' file
dog
cat
horse
turtle
1

You can use this sed command:

$ sed -e "s/', '/\n/g" -e "s/'//g" file 
dog
cat
horse
turtle
0
awk '{gsub(/^.|.$/,"");gsub(/., *./,"\n")} 1' file
dog
cat
horse
turtle

Also see this: http://awk.freeshell.org/PrintASingleQuote If we base on its reference, we can do:

awk '{gsub("\047","");gsub(/, */,"\n")} 1' file
dog
cat
horse
turtle 
  • or:
awk -v q="'" '{gsub(q,"");gsub(/, */,"\n")} 1' file
dog
cat
horse
turtle
0
python -c "for s in eval(input()): print(s)" < file
dog
cat
horse
turtle

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.