bash awk/gsub - 在每行多次出现双引号之间打印所有内容
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14488221/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
awk/gsub - print everything between double quotes in multiple occurrences per line
提问by Travis Crooks
I attempting to print all data between double quotes (sampleField="sampleValue"), but am having trouble to get awkand/or sub/gsubto return all instances of data between the double quotes. I'd then like to print all instances on the respective lines they were found to keep the data together.
我试图打印双引号 ( sampleField="sampleValue")之间的所有数据,但无法获取awk和/或sub/gsub返回双引号之间的所有数据实例。然后我想在找到的相应行上打印所有实例以将数据保持在一起。
Here is a sample of the input.txtfile:
这是该input.txt文件的示例:
deviceId="1300", deviceName="router 13", deviceLocation="Corp"
deviceId="2000", deviceName="router 20", deviceLocation="DC1"
The output I'm looking for is:
我正在寻找的输出是:
"1300", "router 13", "Corp"
"2000", "router 20", "DC1"
I'm having trouble using gsub to remove all of the data between a ,and =. Each time I've tried a different approach, it always just returns the first field and moves onto the next line.
我在使用 gsub 删除 a,和之间的所有数据时遇到问题=。每次我尝试不同的方法时,它总是只返回第一个字段并移动到下一行。
UPDATE:
更新:
I forgot to mention that I won't know how many double quote encapsulated fields will be on each line. It could be 1, 3, or 5,000. Not sure if this affects the solution, but wanted to make sure it was out there.
我忘了提到,我不知道每行有多少双引号封装的字段。它可以是 1、3 或 5,000。不确定这是否会影响解决方案,但想确保它在那里。
采纳答案by Rubens
A sedsolution:
一个sed解决方案:
sed -r 's/[^\"]*([\"][^\"]*[\"][,]?)[^\"]*/ /g'
<<< 'deviceId="1300", deviceName="router 13", deviceLocation="Corp"'
Output:
输出:
"1300", "router 13", "Corp"
Or for a file:
或者对于文件:
sed -r 's/[^\"]*([\"][^\"]*[\"][,]?)[^\"]*/ /g' input.txt
回答by jim mcnamara
awk -F '"' '{printf(" %c%s%c, %c%s%c, %c%s%c\n", 34,, 34, 34, ,34, , 34) } ' \
input file > newfile
is another simpler approach, using quote as a field separator.
是另一种更简单的方法,使用引号作为字段分隔符。
awk 'BEGIN{ t=sprintf("%c", 34)}
{ for(i=1; i<=NF; i++){
if(index($i,t) ){print $i} }; printf("\n")}' infile > outfile
More general awk approach.
更通用的 awk 方法。
回答by glenn Hymanman
awk -F \" '
{
sep=""
for (i=2; i<=NF; i+=2) {
printf "%s\"%s\"", sep, $i
sep=", "
}
print ""
}
' << END
deviceId="1300", deviceName="router 13", deviceLocation="Corp", foo="bar"
deviceId="2000", deviceName="router 20", deviceLocation="DC1"
END
outputs
输出
"1300", "router 13", "Corp", "bar"
"2000", "router 20", "DC1"
回答by Vietnhi Phuvan
awk/sub/gsub/ is the probably neither the most direct way nor the easiest way to get it done. I like one-liners when they make sense:
awk/sub/gsub/ 可能既不是最直接的方法,也不是完成它的最简单的方法。当它们有意义时,我喜欢单行:
(1) In Perl:
(1) 在 Perl 中:
172-30-3-163:ajax vphuvan$ perl -pe 's/device.*?=//g' input.txt
"1300", "router 13", "Corp"
"2000", "router 20", "DC1"
where
-p means "print to screen"
-e means execute the statement between the single quotes
s is a regular expression command which gives the instruction to substitute
g is the switch for the regular expression. /g instructs the program to carry out the substitution /device.*?=// wherever applicable
/device.*?=// is an instruction to replace with an empty string '' any expression that starts with the prefix "device" and that ends just before the closest "=" sign. Note that "deviceId", "deviceName" and "deviceLocation" all start with the prefix "device" and each of them ends just before the "=" sign
(2) In bash:
(2) 在 bash 中:
172-30-3-163:ajax vphuvan$ sed "s/deviceId=//; s/deviceName=//; s/deviceLocation=//" input.txt
"1300", "router 13", "Corp"
"2000", "router 20", "DC1"
In this case, we are instructing sedto run three substitution instructions in a row where "deviceId", "deviceName" and "deviceLocation are each replaced with an empty string ''
在这种情况下,我们指示sed在一行中运行三个替换指令,其中“deviceId”、“deviceName”和“deviceLocation”都被替换为空字符串 ''
It is unfortunate that sed(and sub and gsub) has much weaker support for regular expressions than Perl, which is the gold standard for full regular expression support. In particular, neither sednor sub/gsub support the non-greedy instruction"?", and this failure considerably complicates my life.
不幸的是,sed(以及 sub 和 gsub)对正则表达式的支持比 Perl 弱得多,后者是完全支持正则表达式的黄金标准。特别是,sed和 sub/gsub都不支持非贪婪指令“?”,而这种失败使我的生活变得相当复杂。
回答by krock1516
This is too late but One probable easy solution would be:
这为时已晚,但一种可能的简单解决方案是:
$ awk -F"=|," '{print ,,}' input.txt
"1300" "router 13" "Corp"
"2000" "router 20" "DC1"
回答by Mirage
try this
尝试这个
awk -F\" '{ for(i=2; i<=NF; i=i+2){ a = a"\""$i"\""",\t";} {print a; a="";}}' temp.txt
awk -F\" '{ for(i=2; i<=NF; i=i+2){ a = a"\""$i"\""",\t";} {print a; a="";}}' temp.txt
output
输出
"1300", "router 13", "Corp"
"2000", "router 20", "DC1"

