Using awk's substr
function
This removes the first and last characters from each string:
$ systool -c fc_host -v | awk '/Class Device =/{host=substr($4,2,length($4)-2)}/port_state/{print host,substr($3,2,length($3)-2)}'
host1 Online
How it works:
In the code that you started with, there was the line
host=$4
In the revised code, that is replaced with:
host=substr($4,2,length($4)-2)
The substr
function returns a substring of $4
. In this case, it starts from the second character and extends a length of length($4)-2
. Thus, this includes all characters except the first and last (which are the double quotes).
For the same reason, this command:
print host,$3)
was replaced with:
print host,substr($3,2,length($3)-2)
Using GNU awk's gsub
function
Alternatively, gsub
can be used to remove the double quotes:
$ systool -c fc_host -v | awk '/Class Device =/{gsub("\"","",$4);host=$4}/port_state/{gsub("\"","",$3);print host,$3}'
host1 Online
How it works
This is again just like the code that you started with but with two new commands added:
gsub("\"","",$4)
gsub("\"","",$3)
gsub
does substitutions. In this case, it replaces "
with an empty string, in effect removing the double quotes. On the first line above, it removes them from $4
(which is the host) and on the second line above, it removes them from $3
(which is the port_state
).
Using awk's Field Separator
$ systool -c fc_host -v | awk -F'"' '/Class Device =/{host=$2} /port_state/{print host,$2}'
host1 Online
A very simple option is to use sed as @Dani proposes if you want to remove all double-quotes.
$ echo "This is my program \"Hello World\"" | sed 's/"//g'
This is my program Hello World
Nevertheless, if you want to remove only internal quotes, I would suggest removing all quotes and adding one at the beginning and one at the end as follows.
Let's say we have a file sample.txt with these contents:
$ cat sample.txt
"This is the "First" Line"
"This is the "Second" Line"
"This is the "Third" Line"
Then, if you want to remove only internal quotes, I would suggest the following:
$ cat sample.txt | sed 's/"//g' | sed 's/^/"/' |sed 's/$/"/'
"This is the First Line"
"This is the Second Line"
"This is the Third Line"
Explanation:
sed 's/"//g' removes all double quotes on each line
sed 's/^/"/' adds a double-quote at the beginning of each line
sed 's/$/"/' adds a double-quote at the end of each line
sed 's/|/"|"/g' adds a quote before and after each pipe.
Hope this helps.
EDIT: As per the pipe separator comment, we have to slightly change the command
Let sample.txt be:
$ cat sample.txt
"This is the "First" column"|"This is the "Second" column"|"This is the "Third" column"
Then, adding a replacer command for the pipe give us the final solution.
$ cat sample.txt | sed 's/"//g' | sed 's/^/"/' |sed 's/$/"/' | sed 's/|/"|"/g'
"This is the First column"|"This is the Second column"|"This is the Third column"
The script option
Using this sample.txt file
$ cat sample.txt
"This is the "first" column"|12345|"This is the "second" column"|67890|"This is the "third" column"
And this script
#!/bin/ksh
counter=1
column="initialized"
result=""
while [[ "$column" != "" ]]
do
eval "column=$(cat sample.txt | cut -d"|" -f$counter)"
eval "text=$(cat sample.txt | cut -d"|" -f$counter | grep '"')"
if [[ "$column" = "$text" && -n "$column" ]]
then
if [[ "$result" = "" ]]
then
result="_2quotehere_${column}_2quotehere_"
else
result="${result}|_2quotehere_${column}_2quotehere_"
fi
else
if [[ -n "$column" ]]
then
if [[ "$result" = "" ]]
then
result="${column}"
else
result="${result}|${column}"
fi
fi
fi
echo $result | sed 's/_2quotehere_/"/g' > output.txt
(( counter+=1 ))
done
cat output.txt
exit 0
You will get this:
$ ./process.sh
"This is the first column"|12345|"This is the second column"|67890|"This is the third column"
$ cat output.txt
"This is the first column"|12345|"This is the second column"|67890|"This is the third column"
I hope this is the processing you need.
Let me know!
FINAL EDIT
This script processes the input line you provided, several times included. Only restriction is that all 20 columns MUST BE on the same line.
#!/bin/ksh
rm output.txt > /dev/null 2>&1
column="initialized"
result=""
lineCounter=1
while read line
do
print "LINE $lineCounter: $line"
counter=1
while [[ ${counter} -le 20 ]]
do
eval 'column=$(print ${line} | cut -d"|" -f$counter)'
eval 'text=$(print ${line} | cut -d"|" -f$counter | grep \")'
print "LINE ${lineCounter} COLUMN ${counter}: $column"
if [[ "$column" = "$text" && -n ${column} ]]
then
if [[ "$result" = "" ]]
then
result="_2quotehere_$(echo ${column} | sed 's/\"//g')_2quotehere_"
else
result="${result}|_2quotehere_$( echo ${column} | sed 's/\"//g')_2quotehere_"
fi
else
if [[ "$result" = "" ]]
then
result=${column}
else
result="${result}|${column}"
fi
fi
(( counter+=1 ))
done
(( lineCounter+=1 ))
echo -e $result | sed 's/_2quotehere_/"/g' >> output.txt
result=""
done < input.txt
print "OUTPUT CONTENTS:"
cat output.txt
exit 0
From here, you must be able to get it working for your particular case.
Best Answer
You can just use
cut
for this:-d '"'
tellscut
to use a double quote as its field delimiter.-f2
tells it to take the second field, which is between the first and second quotes - or the first quoted string, exactly what you want.