Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 years ago.
Improve this question
\begin{table}
\begin{tabular}{l | l | c | c }
Name & Hex & dezimal & C-char \\
<cr> & 0x0D & 13 & '\\r' \\ % should read '\r'
<lf> & 0x0A & 10 & '\\n' \\
\end{tabular}
\end{table}
Escaping the '\' preceding 'n' or 'r' to e.g. '\\n' inserts a new line - as the '\\' at the end of the line does.
Using '\n' or '\r' produces weird characters.
How can this be coded properly?
To typeset a backslash in your document, use \textbackslash.
But since it's referring to C code, it might be nicer to format it appropriately in a monospaced font:
\verb|'\r'|
Instead of the pipe (|) you can choose any other character, as long as it doesn't appear in the enclosed text.
Related
This question already has answers here:
Grep string inside double quotes
(4 answers)
Closed 1 year ago.
Based on this question: Bash sed - find hashtags in string; with no solutions for this case (when you have special characters).
This question is well-researched and not a duplicate of this unrelated question as the referred doesn't covers all the asked topics (support to special characters and numbers; grep both between and after/before).
echo "Text and #hashtag" | grep -o '#[[:alpha:]]\+*' | tr -d '"' works successfully, returning #hashtag; that's still related to the mentioned question...
...About this new question with mine own needs (that can be useful to you), this is my version, parsing text between doublequotes instead of after hashtag:
echo '#first = "Yes"' | grep -o '"[[:alpha:]]\+*"' | tr -d '"' and it works, returning Yes.
However, when it have an emoji or other characters such as > and / (example: echo '#first = "✅ Yes"' | grep -o '"[[:alpha:]]\+*"' | tr -d '"') it returns an empty output.
It have to support any kind of character (emojis, html tags, numbers).
This should be useful not only for parsing between characters, but also after a character (such as parsing any #hashtag text) or before.
The way to extract text between double quotes is to match any character except double quote, as many as possible, between double quotes.
grep -o '"[^"]*"' | tr -d '"'
Some test cases:
grep -o '"[^"]*"' <<\___here | tr -d '"'
there is "text" between "double quotes"
just one "?" here, "test me!"
any unpaired double quote " will not match
___here
The second one of these will fail with the current code in your own answer.
Thanks to #Aserre's pointings, I could come up with an answer.
In order for the "get every text when it appear AFTER a charater" and "get every text when it appear BETWEEN quotes" (grep) to work with any character, we have to replace [[:alpha:]] in the block to ...
So, it is:
echo '#first = "✅ Yes"' | grep -o '"...\+"' | tr -d '"' (get anything which is between double quotes)
and:
echo "Text and #hashtag" | grep -o '#...\+' | tr -d '"' (get anything which is after a hashtag)
Update:
If you want to support things with only 1 character (such as numbers ranging from 0 to 9), replace ... to . (single dot)
It works, as in the question, for: emojis, letters, numbers and other special characters.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
i have a file that have variables and values
objective: open the file and replace all id by input id
[FILE]
var1 = 2
id = 3
var3 = 5
id = 12
var4 = 5
and i can't replace the id values to new ones.
here's my code, any help or something will help. thanks
#!/bin/bash
filename=$1
uuid=$2
input="./$filename"
# awk -v find="id " -v field="5" -v newval="abcd" 'BEGIN {FS=OFS="="} {if ($1 == find) $field=newval; print $1}' $input
while IFS= read -r line
do
awk -v find="id " -v field="5" -v newval="abcd" 'BEGIN {FS=OFS="="} {if ($1 == find) $field=newval;}' $input
echo $line
done < "$input"
expected output
execute
./myscript.sh file.cnf 77
expected output:
[FILE]
var1 = 2
id = 77
var3 = 5
id = 77
var4 = 5
I think sed is the right tool for this. You can even use its -i switch and update the file in-place.
$ cat file.txt
var1 = 2
id = 3
var3 = 5
id = 12
var4 = 5
$ NEW_ID=1234
$ sed -E "s/(id\s*=\s*)(.+)/\1${NEW_ID}/g" file.txt
var1 = 2
id = 1234
var3 = 5
id = 1234
var4 = 5
The string inside the quotes is a sed script for substituting some text with different text, and its general form is s/regexp/replacement/flags where "regexp" stands for "regular expression".
In the above example, the script looks for the string "id = ..." with any number of spaces or tabs around the "=" character. I divided the regexp into 2 groups (using parentheses) because we only want to replace the part to the right of the "=" character, and I don't think sed allows partial substitutions, so as a workaround I used \1 in the "replacement", which inserts the contents of the 1st group. The ${NEW_ID} actually gets evaluated by the shell so the value of the variable ("1234") is already part of the string by the time sed processes it. The g at the end stands for "global" and is probably redundant in this case. It makes sure that all occurrences of the regex on every line will get replaced; otherwise sed would only replace the first occurrence on each line.
Not sure. Bash scripts are extremely sensitive. I'm guessing your touch is what is causing this issue for a couple of reasons.
First whenever you touch a file name is should not consist of an operand or prefix unliss it is part of the shell script and $filename is shell or inline block quote. Touch is usually used for binaries or high priority data objects.
Second I'd try changing input and adjusted to $done and instead of echoing the $line echo the entire script using esac or end if instead of a do while loop.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm struggling a little bit with grep pattern matching. I thought ${d%?} would match on all but the last character, but it seems to be matching more aggressively than that.
dbs=$(${db_home}/bin/srvctl config | sort)
counter=1
for d in ${dbs[#]};do
echo -e "dbs[${counter}] = ${d}"
inst2[${d}]=$(sudo ${grid_home}/bin/crsctl stat res -w "((TYPE = ora.database.type) AND (LAST_SERVER = $(hostname -s)))" -f | grep ^USR_ORA_INST_NAME= | grep ${d%?})
echo -e "inst2[${d}] = ${inst2[${d}]}"
I'd expect my output to be something like
dbs[1] = ope3u005
inst2[ope3u005] = USR_ORA_INST_NAME=ope3u0051
dbs[2] = ope3u006
inst2[ope3u006] = USR_ORA_INST_NAME=ope3u0061
But instead I'm getting
dbs[1] = ope3u005
inst2[ope3u005] = USR_ORA_INST_NAME=ope3u0051
USR_ORA_INST_NAME=ope3u0061
dbs[2] = ope3u006
inst2[ope3u006] = USR_ORA_INST_NAME=ope3u0051
USR_ORA_INST_NAME=ope3u0061
It's pretty clearly stripping off more than the last character for matching.
This isn't a use case for where we need to strip off the last character, but I'm trying to find a solution that works for this case as well as the cases where we do need to.
If you strip the final character off "ope3u005" then obviously it's going to match both "ope30051" and "ope3u0061"
How do I describe a quoted string (like in C, Java, etc) in EBNF notation?
I was thinking of this (see below), but the AnyCharacter part will also match the double quotes (").
QuotedString = '"' AnyCharacter* '"' ;
In other words, how do I match all characters except the double quote character ("), but still allow escapes (/")?
You could do something like
string = " printable-chars | nested-quotes "
where
printable chars = letter | digit | ~ # # % _ $ & ' - + /
where
letter = A..Z | a..z | extended ascii
and
digit = 0..9
I think you've got the general idea
Let's say I have a file test.txt with contents:
+-foo.bar:2.4
| bar.foo:1.1:test
\| hello.goobye:3.3.3
\|+- baz.yeah:4
I want to use the tr command to delete all instances of the following set of characters:
{' ', '+', '-', '|', '\'}
Done some pretty extensive research on this but found no clear/concise answers.
This is the command that works:
input:
cat test.txt | tr -d "[:blank:]|\\\+-"
output:
foo.bar:2.4
bar.foo:1.1:test
hello.goobye:3.3.3
baz.yeah:4
I experimented with many combinations of that set and I found out that the '-' was being treated as a range indicator (like... [a-z]) and therefore must be put at the end. But I have two main questions:
1) Why must the backslash be double escaped in order to be included in the set?
2) Why does putting the '|' at the end of the set string cause the tr program to delete everything in the file except for trailing new line characters?
Like this:
tr -d '\-|\\+[:blank:] ' < file
You have to escape the - because it is used for denoting ranges of characters like:
tr -d '1-5'
and must therefore being escaped if you mean a literal hyphen. You can also put it at the end. (learned that, thanks! :) )
Furthermore the \ must be escaped when you mean a literal \ because it has a special meaning needed for escape sequences.
The remaining characters must not being escaped.
Why must the \ being doubly escaped in your example?
It's because you are using a "" (double quoted) string to quote the char set. A double quoted string will be interpreted by the shell, a \\ in a double quoted string means a literal \. Try:
echo "\+"
echo "\\+"
echo "\\\+"
To avoid to doubly escape the \ you can just use single quotes as in my example above.
Why does putting the '|' at the end of the set string cause the tr program to delete everything in the file except for trailing new line characters?
Following CharlesDuffy's comment having the | at the end means also that you had the unescaped - not at the end, which means it was describing a range of characters where the actual range depends on the position you had it in the set.
another approach is to define the allowed chars
$ tr -cd '[:alnum:]:.\n' <file
foo.bar:2.4
bar.foo:1.1:test
hello.goobye:3.3.3
baz.yeah:4
or, perhaps delete all the prefix non-word chars
$ sed -E 's/\W+//' file