Escape hash sign in Yaml multiline text - yaml

Is it possible to escape a hash sign (#) from a multiline text?
...
-
my_story: |
Line 1
Line 2
# Hash line
What I was hoping to get is:
array {
'my_story' => 'Line 1
Line 2
# Hash line'
}
If I wrap the hash line with quotes I get them in the text:
'Line 1
Line 2
"# Hash line"'
Any ideas..?

What you wrote is perfectly fine and '#' should be correctly processed. The following code works just fine in Python 3 (pyyaml)
data="""
-
my_story: |
Line 1
Line 2
# Hash line
"""
import yaml
deserializedData = yaml.load ( data )
print ( deserializedData[0]['my_story'] )
The above line prints
Line 1
Line 2
# Hash line

Related

How to check a character value at a position on a line and then add a character at another position on an another line using sed command

Eg. Input Text file
line 1 - Abchsffmskdv
line 2 - bsdvnld
line 3 - fsdgdhdh
If line 1, position 9 is s, then change line 3, position 4 to k
Output:
line 1 - Abchsffmskdv
line 2 - bsdvnld
line 3 - fsdkdhdh
Please try the following:
sed '
/^.\{8\}s/ { # if the 9th char == "s" then
$!n # flush current line and read next line (unless eof)
$!n # same as above to proceed to the line after next
$!s/^\(.\{3\}\)./\1k/ # replace the 4th char with "k"
}' input.txt
or as a one-liner:
sed '/^.\{8\}s/{$!n; $!n; $!s/^\(.\{3\}\)./\1k/}' input.txt
input.txt looks like:
Abchsffmskdv
bsdvnld
fsdgdhdh
iiiiiiiisiii
iiiiiii
iiiiiiii
output:
Abchsffmskdv
bsdvnld
fsdkdhdh
iiiiiiiisiii
iiiiiii
iiikiiii
You'll see the script above replaces the 4th character of the next next
line if the pattern is found regardless of the line number.
If you want to fix the line number to e.g. the 1st line, try instead:
sed '
1 {
/^.\{8\}s/ {
$!n
$!n
$!s/^\(.\{3\}\)./\1k/
}
}' input.txt
output:
Abchsffmskdv
bsdvnld
fsdkdhdh
iiiiiiiisiii
iiiiiii
iiiiiiii
which modifies the 3rd line only.
This might work for you (GNU sed):
sed -E '1h;3{G;s/(...).(.*)\n.{8}s/\1k\2/}' file
Store the first line in the hold space and append it to line 3 and pattern match for the desired criteria.
An alternative:
sed -E '1h;3{x;/^.{8}s/{x;s/./k/4;x};x}' file

Ruby - How to get rid of escape character and "\n" while converting string to hash value?

In Ruby, i'm trying to convert a string to a hash value. It shows up with escapse character and "\n" in the string.
Eg:
hashex = { keyex: 'example "test" line 1
line 2 "test2"'}
puts hashex
It is printing the result as
{:keyex=>"example \"test\" line 1\n line 2 \"test2\""}
I need to get the result as
{ keyex: 'example "test" line 1
line 2 "test2"'}
preserving the newline (not '\n') and the "". Kindly help.
Note
{:keyex=>"example \"test\" line 1\n line 2 \"test2\""}
is just the way Ruby represents the hash. It is 100% the same object as :
{ keyex: 'example "test" line 1
line 2 "test2"'}
even though it might look different.
Code
You could replace "\\n" from inspect with newlines, \" with " and " with ' :
hashex = { keyex: 'example "test" line 1
line 2 "test2"'}
puts hashex.inspect.gsub("\\n", "\n").gsub('"', "'").gsub("\\'",'"')
# {:keyex=>'example "test" line 1
# line 2 "test2"'}

Ruby one liner to replace only lines that match, discard others

Looking for the ruby one liner substitute to print out a substitution only if the line matches the regular expression:
echo -e "Line 1\nLine 2\nLine 3" | perl -ne "print if s/Line 2/Line 2 replaced, others discarded/g"
Input:
Line 1
Line 2
Line 3
Output:
Line 2 replaced, others discarded
As I know, there is no equivalent to -ne shorthand in ruby. So it will be little longer:
echo -e "Line 1\nLine 2\nLine 3" | ruby -e 'puts $<.read.lines.map {|l| l =~ /Line 2/ ? l.gsub(/Line 2/, "Line 2 replaced, others discarded") : nil }.compact'
Where:
$< also ARGF (docs) is Stream for file argument or STDIO
$<.read will read it all to string
$<.read.lines split by new line character, returns array
map {|l| ... } will collect result of expression in a block to new array
l =~ /Line 2/ check if string match Regex
l.gsub(/Line 2/, "Line 2 replaced") will replace all "Line 2" to "Line 2 replaced"
.compact will remove nil values from array (return new array without nil's)
puts [] will print each element of array on new line
Probably ruby is not a best chose for this task, I would choose sed or do it in text editor. Most of text editors can find and replace by regex nowdays

Why does my IO.write insert a "%" sign at the end of output?

I use this line to read from temp.dat, which contains "100"
fahrenheit = IO.read("temp.dat").to_i * 9 / 5 + 32
Now, to write this result in another file;
Method 1
f = File.new("temp.out", "w")
f.puts fahrenheit
cat temp.out
212
Method 2
IO.write("temp.out", fahrenheit)
cat temp.out
212%
Why does my IO.write insert a “%” sign at the end of output?
It doesn't. Here's the binary content of the file. That % character is the command prompt of your shell, which is confused by the lack of EOL in the file. POSIX-compliant text files should always end lines with end-of-line character.

Read files line by line with \r, \n or \r\n as line separator

I want to process files line by line. However, these files have different line separators: "\r", "\n" or "\r\n". I don't know which one they use or which kind of OS they come from.
I have two solutions:
using bash command to translate these separators to "\n".
cat file |
tr '\r\n' '\n' |
tr '\r' '\n' |
ruby process.rb
read the whole file and gsub these separators
text=File.open('xxx.txt').read
text.gsub!(/\r\n?/, "\n")
text.each_line do |line|
do some thing
end
but the second solution is not good when the file is huge. See reference. Is there any other ruby idiomatic and efficient solution?
I suggest you first determine the line separator. I've assumed that you can do that by reading characters until you encounter "\n" or "\r" (or reach the end of the file, in which case we can regard "\n" as the line separator). If the character "\n" is found, I assume that to be the separator; if "\r" is found I attempt to read the next character. If I can do so and it is "\n", I return "\r\n" as the separator. If "\r" is the last character in the file or is followed by a character other than "\n", I return "\r" as the separator.
def separator(fname)
f = File.open(fname)
enum = f.each_char
c = enum.next
loop do
case c[/\r|\n/]
when "\n" then break
when "\r"
c << "\n" if enum.peek=="\n"
break
end
c = enum.next
end
c[0][/\r|\n/] ? c : "\n"
end
Then process the file line-by-line
def process(fname)
sep = separator(fname)
IO.foreach(fname, sep) { |line| puts line }
end
I haven't converted "\r" or "\r\n" to "\n", but of course you could do that easily. Just open a file for writing and in process read each line and write it to the output file with the default line separator.
Let's try it (for clarity I show the value returned by separator):
fname = "temp"
IO.write(fname, "slash n line 1\nslash n line 2\n")
#=> 30
separator(fname)
#=> "\n"
process(fname)
# slash n line 1
# slash n line 2
IO.write(fname, "slash r line 1\rslash r line 2\r", )
#=> 30
separator(fname)
#=> "\r"
process(fname)
# slash r line 1
# slash r line 2
IO.write(fname, "slash r slash n line 1\r\nslash r slash n line 2\r\n")
#=> 48
separator(fname)
#=> "\r\n"
process(fname)
# slash r slash n line 1
# slash r slash n line 2

Resources