I have a file like this:
#!/bin/bash
echo $(date "+%F %R:%S") ":: yum update"
/usr/bin/yum update -y
I want to convert that to exactly this quoted string:
"#!/bin/bash\necho $(date \"+%F %R:%S\") \":: yum update\"\n/usr/bin/yum update -y\n"
Any method I have used is matching the line feeds but converts them to a line feed instead of to "\n". So these examples:
sed 's/\n/\n/g' file
sed 's/\n/\\\n/g' file
tr '\n' '\n' <file
tr '\n' "\n" <file
all result in exactly the same output as the file itself. So how do I match the line feed character and replace it with the actual string "\n" and not something that will itself be recognized as a line feed?
Here, you want two characters, slash and n, to replace a single newline. Consequently, tr is not a good choice.
It wasn't clear to me if you wanted actual backslashes to precede your double quotes or not. The answers below assume that you do. If you don't, it is simple enough the remove those substitutions.
Using awk
$ awk '{gsub(/"/, "\\\""); printf "%s\\n",$0}' file
#!/bin/bash\necho $(date \"+%F %R:%S\") \":: yum update\"\n/usr/bin/yum update -y\n
Using sed
$ sed ':again; N; $!b again; s/"/\\"/g; s/\n/\\n/g; s/$/\\n/' file
#!/bin/bash\necho $(date \"+%F %R:%S\") \":: yum update\"\n/usr/bin/yum update -y\n
Perl:
perl -0777 -pe 's/\n/\\n/g; s/"/\\"/g' file
tr cannot do this job because it cannot translate one char (\n) into a 2-char string (\n).
Related
I need a sed regex command that will output every line in a while that ends with 'html', and does NOT start with 'a'.
Would my current code work?
sed 's/\[^a]\*\.\(html)\/p' text.txt
The sed command would be
sed -n '/^[^a].*html$/p'
But the canonical command to print matching lines is grep:
grep '^[^a].*html$'
Sed just over complicates things...you can use grep to handle that easily!
egrep "^[^a].+\.html$" -f sourcefile > text.txt
//loads file from within the program egrep
egrep "^[^a].+\.html$" < sourcefile > text.txt
//Converts stdin file descriptor with the input redirect
//to sourceFile for this stage of the` pipeline
are equivalent functionally.
or
pipe input | xargs -n1 egrep "^[^a].+\.html$" > text.txt
//xargs -n1 means take the stdin from the pipe and read it one line at a time in conjunction with the single command specified after any other xargs arguments
// ^ means from start of line,
//. means any one character
//+ means the previous matched expression(which can be a
//(pattern group)\1 or [r-ange], etc) one or more times
//\. means escape the single character match and match the period character
//$ means end of line(new line character)
//egrep is short for extended regular expression matches which are really
nice
(assuming you aren't using a pipe or cat, etc)
You can convert a newline delimited file into a single input line with this command:
cat file | tr -d '\n' ' '
//It converts all newlines into a space!
Anyway, get creative with simple utilities and you can do a lot:
xargs, grep, tr are a good combo that are easy to learn. Without the sedness of it all.
Don't do this with sed. Do it with two different calls to grep
grep -v ^a file.txt | grep 'html$'
The first grep gets all the lines that do not start with "a", and sends the output from that into the second grep, which pulls out all the lines that end with "html".
I have simple sed command:
#!/bin/bash
COMMAND=$1
sed -e "s#COMMAND#$COMMAND#
The value for command should be a new line for every command but i cannot figure out how to give them to sed and sed put every command on new line. What i have tried is:
./script 'ls\n date\n uname\n'
Regards!
If I'm understanding your question, you are looking to replace a representation of newlines within a string (i.e. a backslash character, followed by an 'n') as actual printed newlines.
The following script takes a single quoted string (the input as shown in your question) containing the literals '\n' and converts those into actual new lines.
#!/bin/bash
echo -n $1 | sed -e 's#\\n#\n#g'
Example usage:
[user#localhost ~]$ ./simple_sed.sh 'ls\ndate\nuname\n'
ls
date
uname
The changes needed from your script are to
echo the argument, otherwise sed expects a file and will do nothing;
match the \\n and replace it with a newline; and
add a 'g' to the end which will continue searching within a line after a replacement has occurred (read: multiple \n are substituted in a single line).
In a file, I need to replace all newlines (not the escape sequence '\n', but the actual newline) with a string. All the questions I've found on SO have been the other way around; i.e. replacing a string with a literal newline. This is on a Mac.
I've tried the following
sed -i '' 's/\
/STOP/g' file.txt
But it gives me an "unterminated substitute pattern" error.
While it can be done using sed also but doing this with awk is much simpler:
awk -v ORS='STOP' '1' file
This changes output record separator to STOP instead of default \n.
Update: Here is a sed version to do same on OSX:
sed -i.bak -n -e 'H;${x;s/\n/STOP/g;p;}' file
How do I replace the first 100 characters of all lines in a file using awk? There is no field delimiter in this file. All fields are fixed width. And given the variation in the data, I cannot use a search and replace.
How about sed? To replace the first 100 characters with say A:
$ sed -r 's/.{100}/A/' file
If you're happy with the results rewrite the file using -i:
$ sed -ri 's/.{100}/A/' file
awk '{print "replacing text..." substr($0,100)}'
Use pure shell.
#!/usr/bin/env bash
# read each line into shell variable REPLY
while read -r ; do
echo "REPLACE text ... ${REPLY:100}"
done <file
Explanation
REPLY is shell variable, refer http://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html. Set to the line of input read by the read builtin command when no arguments are supplied
${REPLY:100} - get the string after 100 characters.
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?
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).
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.
This sed should work for ignoring empty lines as well:
sed -i.bak 's/^..*$/"&"/' inFile
or
sed 's/^.\{1,\}$/"&"/' inFile
Use sed:
sed -e 's/^\|$/"/g' file
More effort needed if the file contains empty lines.
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
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
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.
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
$