I've been trying to manipulate a single line in a file without much success.
test.txt
10.20.30.40 "User 1" 73.15.16.24 NewUser 124.18.21.17 "User 2" 27.76.58.248 "User 3" 39.16.87.227 "User 4" 211.129.20.52 "User 5" 175.15.118.110 "User 6"
If you notice the second line doesn't have quotes around the last word. I have been trying to figure out a way to put quotes around that and save it, either in another file, or preferably in the original.
When I used this command:
cat test.txt | grep -v '".*"' | sed -i 's/\([A-Z]\)/"\1/g'
It finds the correct line and places a quote at the beginning of the word, but then puts another before the U, which isn't what I need. I could always use sed to place a quote at the last position of course, but it would be nice to encompass the entire word.
If I then use the sed command with the -i and point it to the original file, it then throws quotes around every word when saved, which is also what I'm not wanting.
Any help is appreciated, I've been trying to solve this for a couple of days now.
CodePudding user response:
Using sed
$ sed -i.bak '/"/!{s/[[:alpha:]]\ \( \S\ \)\?$/"&"/}' input_file
10.20.30.40 "User 1"
73.15.16.24 "NewUser"
124.18.21.17 "User 2"
27.76.58.248 "User 3"
39.16.87.227 "User 4"
211.129.20.52 "User 5"
175.15.118.110 "User 6"
-i
will allow you to save your file in place
.bak
will create a backup of the original with .bak extension
CodePudding user response:
You can use
sed -E 's/^([0-9] (\.[0-9] ){3})[[:space:]] ([^[:space:]"] )$/\1 "\3"/' file > newfile
With GNU sed:
sed -i -E 's/^([0-9] (\.[0-9] ){3})\s ([^[:space:]"] )$/\1 "\3"/' file
Details:
^
- start of string([0-9] (\.[0-9] ){3})
- one or more digits and then 3 occurrences of.
and one or more digits[[:space:]]
- one or more whitespaces([^[:space:]"] )
- Group 3: one or more chars other than"
and whitespace$
- end of string.
See the online demo:
#!/bin/bash
s='10.20.30.40 "User 1"
73.15.16.24 NewUser
124.18.21.17 "User 2"
27.76.58.248 "User 3"
39.16.87.227 "User 4"
211.129.20.52 "User 5"
175.15.118.110 "User 6"'
sed -E 's/^([0-9] (\.[0-9] ){3})[[:space:]] ([^[:space:]"] )$/\1 "\3"/' <<< "$s"
Output:
10.20.30.40 "User 1"
73.15.16.24 "NewUser"
124.18.21.17 "User 2"
27.76.58.248 "User 3"
39.16.87.227 "User 4"
211.129.20.52 "User 5"
175.15.118.110 "User 6"
CodePudding user response:
A pure bash solution which may be a little easier to read and maintain than sed:
#!/bin/bash
# read each line of the file into an array
while read -ra line ; do
# "user" is everything after the first token in the line
user="${line[*]:1}"
# if user isn't surrounded by quotes then add them,
# otherwise just print the line verbatim
if [[ "${user}" != \"*\" ]] ; then
echo "${line[0]} \"${user}\""
else
echo "${line[@]}"
fi
done < test.txt > test.txt.new
# Put the edited file back in place over top of
# the original file. Start off commented in case
# you want to diff before overwriting the original.
# mv test.txt.new test.txt
CodePudding user response:
Using awk:
awk '{print (NR==2) ? $1 " \"" $2 "\"" : $0}' inputfile
Output:
10.20.30.40 "User 1"
73.15.16.24 "NewUser"
124.18.21.17 "User 2"
27.76.58.248 "User 3"
39.16.87.227 "User 4"
211.129.20.52 "User 5"
175.15.118.110 "User 6"
Or a bit more generic using a regex:
awk '{ print ($2 ~ /\"*\"/) ? $0 : $1 " \"" $2 "\""}' t.dat
Output:
10.20.30.40 "User 1"
73.15.16.24 "NewUser"
124.18.21.17 "User 2"
27.76.58.248 "User 3"
39.16.87.227 "User 4"
211.129.20.52 "User 5"
175.15.118.110 "User 6"
With GNU awk (depending on version) you may be able to edit inplace as well