问题
I would like to print text according some conditions: print lines starting \hello (that works) and I don't know how to add a condition that would wite \a some text \b from this:
\item[\word{\small 1}]: \a some text \b
\item[\word{\small 3}]: \a some text \b
I look for a condition that would delete the first part of a line that is always same except a number \item[\word{\small 1}]: or a condition that would print text between \a and \b included form the line that included \a and \b.
awk '
/\\hello/
/\\item\[\\word\{\\small ?\}\]\:/{
next
}
' file.txt
file.txt:
text
\hello jgfk
4
5
\item[\word{\small 1}]: \a some text \b
\item[\word{\small 3}]: \a some text \b
456465
text
\hello hello
desired result:
\hello jgfk
\a some text \b
\a some text \b
\hello hello
EDIT
Case when the code doesn't work:
\a
\b
\item[\textcircled{\tiny 1}]: \a \bb \perp \unit{\rho} \Rightarrow \bb \cdot\unit{\rho}=0 \b
The output should be:
\a \bb \perp \unit{\rho} \Rightarrow \bb \cdot\unit{\rho}=0 \b
回答1:
Could you please try following.
awk '/\\hello/; match($0,/\\a.*\\b/){print substr($0,RSTART,RLENGTH)}' Input_file
Output will be as follows.
\hello jgfk
\a some text \b
\a some text \b
\hello hello
Explanation of above code:
awk ' ##Starting awk program here.
/\\hello/ ##Checking condition if a line has string \hello then by not mentioning any action it will simply print the current line.
match($0,/\\a.*\\b/){ ##Using match function of awk to match a REGEX where it matches from \\a till \\b of a line, here I have given 2 times \\ to make \ as a a literal character.
print substr($0,RSTART,RLENGTH) ##Printing sub-string from value of RSTART till value of RLENGTH, where RSTART and RLENGTH variables will be set when a regex is found by match function.
} ##Closing BLOCK for match function.
' Input_file ##mentioning Input_file name here.
From man awk match function's definition:
match(s,r) Returns the index of the first longest match of regular expression r in string s. Returns 0 if no match. As a side effect, RSTART is set to the return value.RLENGTH is set to the length of the match or -1 if no match. If the empty string is matched, RLENGTH is set to 0, and 1 is returned if the match is at the front, and length(s)+1 is returned if the match is at the back.
RLENGTH length set by the last call to the built-in function, match() RSTART index set by the last call to match()
回答2:
You have a good answer from @RavinderSingh13, but you can also do it using conditions before your rules and next, e.g.
awk -F': ' 'NF==2 {print $2; next} $1~/^[\\]/' file
Where -F': ' sets the field separator to ": " and then NF==2 checks if you have 2 fields and if so outputs the second field and calls next to skip remaining rules and get the next record. The second rule checks whether the first character is '\' and if so, prints the record.
Example Use/Output
With your input in file
$ awk -F': ' 'NF==2 {print $2; next} $1~/^[\\]/' file
\hello jgfk
\a some text \b
\a some text \b
\hello hello
Note: if there is the potential that you may have lines with 2 fields that do not start with '\' that you don't want to include, you can add the limiting condition to only consider lines beginning with '\' for output with:
awk -F': ' '$1~/^[\\]/ {if (NF==2) print $2; else print $0}' file
(same output)
来源:https://stackoverflow.com/questions/58678476/printing-text-in-awk-conditions