Using awk to split string with \n followed by ' and , - linux

If given the string '1234␤',56789, how can I use awk to split by the sequence ␤',? Here ␤ represents a literal newline character.
Right now I have,
echo $LINE | awk -F'\\\\n',' '{ print $1}'
The split doesn't happen with this. Any advice?

Try to print all fields using the value of -F
echo "1234\n',56789," | awk -F "[',]+" -v ORS="" '{$1=$1}1'
line="1234\n',56789,"; echo "$line" | awk -F "[',]+" -v ORS="" '{$1=$1; print $0}'
Output
1234\n 56789
To print a specific field
echo "1234\n',56789," | awk -F "[',]+" -v ORS="" '{$1=$1; print $1}'
line="1234\n',56789,"; echo "$line" | awk -F "[',]+" -v ORS="" '{$1=$1; print $1}'
Output
1234\n

Related

Strip a part of string in linux

Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 is my string and the result I want is vm-1.0.3
What is the best way to do this
Below is what I tried
$ echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 | awk -F _ {'print $2'} | awk -F - {'print $1,$2'}
vm 1.0.3
I also tried
$ echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 | awk -F _ {'print $2'} | awk -F - {'print $1"-",$2'}
vm- 1.0.3
Here I do not need space in between
I tried using cut and I got the expected result
$ echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 | awk -F _ {'print $2'} | cut -c 1-8
vm-1.0.3
What is the best way to do the same?
Making assumptions from the 1 example you provided about what the general form of your input will be so it can handle that robustly, using any sed:
$ echo 'Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2' |
sed 's/^[^-]*-[^-]*-[^_]*_\(.*\)-[^-]*$/\1/'
vm-1.0.3
or any awk:
$ echo 'Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2' |
awk 'sub(/^[^-]+-[^-]+-[^_]+_/,"") && sub(/-[^-]+$/,"")'
vm-1.0.3
You don't need 2 calls to awk, but your syntax with the single quotes outside the curly's, including printing the hyphen:
echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 |
awk -F_ '{print $2}' | awk -F- '{print $1 "-" $2}'
If your string has the same format, let the field separator be either - or _
echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 | awk -F"[-_]" '{print $4 "-" $5}'
Or split the second field on - and print the first 2 parts
echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 | awk -F_ '{
split($2,a,"-")
print a[1] "-" a[2]
}'
Or with gnu-awk a bit more specific match with a capture group:
echo Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2 |
awk 'match($0, /^Apps-[^_]*_(vm-[0-9]+\.[0-9]+\.[0-9]+)/, a) {print a[1]}'
Output
vm-1.0.3
This is the easiest I can think of:
echo "Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2" | cut -c 25-32
Obviously you need to be sure about the location of your characters. In top of that, you seem to be have two separators: '_' and '-', while both characters also are part of the name of your entry.
echo 'Apps-10.00.00R000-B1111_vm-1.0.3-x86_64.qcow2' | sed -E 's/^.*_vm-([0-9]+).([0-9]+).([0-9]+)-.*/vm-\1.\2.\3/'

Using awk to separate an output containing a tab and a "/" separators into a delimited format

I'll appreciate help in converting this output to a pipe delimited
I have the following output
abcde1234 /path/A/file1
test23455 /path/B/file2345
But I would like in
abcde1234|file1
test23455|file2345
In awk, If you set FS as [[:blank:]]+/|/ you can print the first and last fields:
awk -v FS='[[:blank:]]+/|/' -v OFS='|' '{print $1, $NF}' file
abcde1234|file1
test23455|file2345
Here is a one-liner awk solution:
awk -v FS='[ \t].*/' -v OFS='|' '{$1=$1}1' file
and, a sed one-liner:
sed 's%[[:blank:]].*/%|%' file
and a pure bash one
while read -r; do echo "${REPLY%%[[:blank:]]*}|${REPLY##*/}"; done < file
try to use cut 🤷🏻‍♀️.
abcde1234 /path/A/file1
test23455 /path/B/file2345
while IFS= read -r line; do
value1=$(echo $line | cut -d ' ' -f1)
value2=$(echo $line | cut -d '/' -f4)
printf "$value1 $value2\n"
done < <(cat list)

Awk: parse node names out of "40*r13n15:40*r10n61:40*r11n18:40*r09n15"

I have a linux script for selecting the node.
For example:
4
40*r13n15:40*r10n61:40*r11n18:40*r09n15
The correct result should be:
r13n15
r10n61
r11n18
r09n15
My linux script content is like:
hostNum=`bjobs -X -o "nexec_host" $1 | grep -v NEXEC`
hostSer=`bjobs -X -o "exec_host" $1 | grep -v EXEC`
echo $hostNum
echo $hostSer
for i in `seq 1 $hostNum`
do
echo $hostSer | awk -F ':' '{print '$i'}' | awk -F '*' '{print $2}'
done
But unlucky, I got nothing about node information.
I have tried:
echo $hostSer | awk -F ':' '{print "'$i'"}' | awk -F '*' '{print $2}'
and
echo $hostSer | awk -F ':' '{print '"$i"'}' | awk -F '*' '{print $2}'
But there are wrong. Who can give me a help?
One more awk:
$ echo "$variable" | awk 'NR%2==0' RS='[*:\n]'
r13n15
r10n61
r11n18
r09n15
By setting the record separtor(RS) to *:\n , the string is broken into individual tokens, after which you can just print every 2nd line(NR%2==0).
You can use multiple separators in awk. Please try below:
h='40*r13n15:40*r10n61:40*r11n18:40*r09n15'
echo "$h"| awk -F '[:*]' '{ for (i=2;i<=NF;i+=2) print $i }'
**edited to make it generic based on the comment from RavinderSingh13.

declare variables in the same line shell script

Below is a part of my script where I used different lines for different variable.In the first two lines command used is similar though not same , is there a way to reduce these five lines:
oldv=$( sed -n "${c}p" ~/grepoutput | awk '{print $3 }')
line=$(sed -n "${c}p" ~/grepoutput | awk -F":" '{print $2 }')
newv=$( sed -n "${c}p" ~/vpkglist | awk '{print $3 }' )
oldr=$( sed -n "${c}p" ~/vpkglist | awk '{print $4 }' )
newr=$( sed -n "${c}p" ~/vpkglist | awk '{print $5 }' )
In the first two lines it`s 'grepoutput' is the same file and bottom three lines 'vpkglist' remains same.

how to split "1$$$$" use awk

if I have a string like "sn":"1$$$$12056597.3,2595585.69$$", how can I use awk to split "1$$$$"
I tried
**cat $filename | awk -F "\"1\$\$\$\$" '{ print $2 }'**
**cat $filename | awk -F "\"1$$$$" '{ print $2 }'**
but all failed
any number of $ use
echo '"1$$$$12056597.3,2595585.69$$"' | awk -F '"1[$]+' '{ print $2 }'
exactly 4 use
echo '"1$$$$12056597.3,2595585.69$$"' | awk -F '"1[$]{4}' '{ print $2 }'
to help debug problems with escape characters in the shell you can use the built-in shell command set which will print the arguments that are being passed to awk after the shell has interpreted any escape characters and replaced shell variables
In this case the shell first interprets \$ as an escape for a plain $
set -x
echo '"1$$$$12056597.3,2595585.69$$"'|awk -F "\"1\$\$\$\$" '{ print $2 }'
+ echo '"1$$$$12056597.3,2595585.69$$"'
+ awk -F '"1$$$$' '{ print $2 }'
You can use \$ so the \$ get to awk, but \$ is interpreted in awk regular expressions as a $ anyway. At least awk is nice enough to warn you...
echo '"1$$$$12056597.3,2595585.69$$"'|awk -F "\"1\\$\\$\\$\\$" '{ print $2 }'
+ echo '"1$$$$12056597.3,2595585.69$$"'
+ awk -F '"1\$\$\$\$' '{ print $2 }'
awk: warning: escape sequence `\$' treated as plain `$'
Turn off debugging with
set +x
echo '"1$$$$12056597.3,2595585.69$$"' | awk -F '"1[$]+' '{ print $2 }' |sed 's/.\{3\}$//'
Or if you want to split both float digit:
echo '"1$$$$12056597.3,2595585.69$$"' | awk -F '"1[$]+' '{ print $2 }' |sed 's/.\{3\}$//' |awk 'BEGIN {FS=","};{print $1}'
And
echo '"1$$$$12056597.3,2595585.69$$"' | awk -F '"1[$]+' '{ print $2 }' |sed 's/.\{3\}$//' |awk 'BEGIN {FS=","};{print $2}'

Resources