bash 输出到 csv 列
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25788520/
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
bash output to csv columns
提问by jayFour
BIG EDIT for a better understanding:is there a possibility in bashto put my output (lines) to columns in csv files (regarding the following challenge).
大编辑以获得更好的理解:bash 中是否有可能将我的输出(行)放入 csv 文件中的列(关于以下挑战)。
my script:
我的脚本:
#!/bin/bash
## get ports, status, vlan
devices=`ls *.txt`
for device in $devices
do
output=`echo $device | awk -F"." {'print '}`
echo "Port;Status;VLAN\r" > $output".csv"
port=`cat $device | awk 'BEGIN {OFS=";"}; /Fa[0-9]|Gi[0-9]|Te[0-9]/ && /disabled|connected/ {print }'`
stat=`cat $device | awk 'BEGIN {OFS=";"}; /Fa[0-9]|Gi[0-9]|Te[0-9]/ && /disabled|connected/ {print <input-file.txt>
Port Name Status Vlan Duplex Speed Type
Fa0/1 disabled 1 auto auto 10/100BaseTX
Fa0/2 disabled 1 auto auto 10/100BaseTX
Fa0/3 disabled 1 auto auto 10/100BaseTX
Fa0/4 disabled 1 auto auto 10/100BaseTX
Fa0/5 disabled 1 auto auto 10/100BaseTX
Fa0/6 disabled 1 auto auto 10/100BaseTX
Fa0/7 disabled 1 auto auto 10/100BaseTX
Fa0/8 disabled 1 auto auto 10/100BaseTX
Fa0/9 disabled 1 auto auto 10/100BaseTX
Fa0/10 xxxx-xxx-xxx 0004. connected 3 full 100 10/100BaseTX
Fa0/11 xxxx-xxx-xxx bge0 connected 3 a-full a-100 10/100BaseTX
Fa0/12 xxxx-xxx-xxx iLO connected 2 a-full a-100 10/100BaseTX
Fa0/13 xxxx-xxx-xxx bge0 connected 2 a-full a-100 10/100BaseTX
Fa0/14 disabled 1 auto auto 10/100BaseTX
Fa0/15 xxxx-xxx-vpn bge0 connected 4 a-full a-100 10/100BaseTX
Fa0/16 xxxx-xxx-vpn ilO connected 2 a-full a-100 10/100BaseTX
Fa0/17 xxxx-xxx xx.xx.xx. connected 2 a-full a-100 10/100BaseTX
Fa0/18 xxxxxx-xxx1 connected 2 a-full a-100 10/100BaseTX
Fa0/19 disabled 1 auto auto 10/100BaseTX
Fa0/20 disabled 1 auto auto 10/100BaseTX
Fa0/21 xxxxx-xxxxx disabled 1 auto auto 10/100BaseTX
Fa0/22 xxxxxx-xxx disabled 1 auto auto 10/100BaseTX
Fa0/23 xxxx-xxx disabled 2 auto auto 10/100BaseTX
Fa0/24 xxxxxx-xxxx disabled 1 auto auto 10/100BaseTX
Fa0/25 disabled 1 auto auto 10/100BaseTX
Fa0/26 disabled 1 auto auto 10/100BaseTX
Fa0/27 disabled 1 auto auto 10/100BaseTX
Fa0/28 disabled 1 auto auto 10/100BaseTX
Fa0/29 disabled 1 auto auto 10/100BaseTX
Fa0/30 disabled 1 auto auto 10/100BaseTX
Fa0/31 disabled 1 auto auto 10/100BaseTX
Fa0/32 disabled 1 auto auto 10/100BaseTX
Fa0/33 disabled 1 auto auto 10/100BaseTX
Fa0/34 disabled 1 auto auto 10/100BaseTX
Fa0/35 disabled 1 auto auto 10/100BaseTX
Fa0/36 disabled 1 auto auto 10/100BaseTX
Fa0/37 disabled 1 auto auto 10/100BaseTX
Fa0/38 disabled 1 auto auto 10/100BaseTX
Fa0/39 disabled 1 auto auto 10/100BaseTX
Fa0/40 disabled 1 auto auto 10/100BaseTX
Fa0/41 disabled 1 auto auto 10/100BaseTX
Fa0/42 disabled 1 auto auto 10/100BaseTX
Fa0/43 disabled 1 auto auto 10/100BaseTX
Fa0/44 disabled 1 auto auto 10/100BaseTX
Fa0/45 disabled 1 auto auto 10/100BaseTX
Fa0/46 disabled 1 auto auto 10/100BaseTX
Fa0/47 disabled 1 auto auto 10/100BaseTX
Fa0/48 disabled 1 auto auto 10/100BaseTX
Gi0/1 Xxxxxxxx Xxxxx xx connected trunk a-full a-1000 10/100/1000BaseTX SFP
Gi0/2 Xxxxx xxxxxxx Xxx connected trunk a-full a-1000 1000BaseSX SFP
Gi0/3 disabled 1 auto auto Not Present
Gi0/4 disabled 1 auto auto Not Present
}' | awk 'match(<output.csv>
| Port | Status | VLAN |
| Fa0/1 | disabled | 1 |
| Fa0/2 | disabled | 1 |
| Fa0/3 | disabled | 1 |
| Fa0/4 | disabled | 1 |
| Fa0/5 | disabled | 1 |
| Fa0/6 | disabled | 1 |
| Fa0/7 | disabled | 1 |
| Fa0/8 | disabled | 1 |
| Fa0/9 | disabled | 1 |
| Fa0/10 | connected | 3 |
and so on
,"connected|disabled.*"){print substr(awk 'BEGIN{FIELDWIDTHS = "10 18 13 11"}{printf "| %s | %s | %s |\n", ,,}' "$device"
,RSTART)}' | awk '{print }'`
vlan=`cat $device | awk 'BEGIN {OFS=";"}; /Fa[0-9]|Gi[0-9]|Te[0-9]/ && /disabled|connected/ {print paste file.txt anotherf.txt
}' | awk 'match(paste -d, <(awk '{print }' file.txt) <(awk '{print }' anotherf.txt)
,"connected|disabled.*"){print substr(paste -d, <(cut -f1 -d' ' file.txt) <(cut -f1 -d' ' anotherf.txt)
,RSTART)}' | awk '{print }'`
var=$(paste -d, <(echo "$port") <(echo "$stat") <(echo "$vlan"))
echo "$var" >> output."csv"
done
.
.
paste -d, <(echo "$var1") <(echo "$var2")
result of script output should be:
脚本输出的结果应该是:
$ awk 'getline line<ARGV[2]{split(line,a)}NR==FNR{print ,a[1]}' file.txt anotherf.txt
1 one
2 two
3 three
4 four
5 five
Issue: after trying the "paste" command (thanks guys) .. i'm getting the following error: Syntax error: "(" unexpected
问题:尝试“粘贴”命令后(谢谢大家).. 我收到以下错误:语法错误:“(”意外
回答by Tom Fenech
Assuming you have GNU awk, the lines inside your loop can be compressed to something like this:
假设你有 GNU awk,你的循环中的行可以被压缩成这样:
##代码##If you have a different awk, the command will be more complicated but it is still possible to do what you want in one awk statement.
如果您有不同的 awk,该命令会更复杂,但仍然可以在一个 awk 语句中执行您想要的操作。
Some points on your attempt:
您尝试的一些要点:
- Make sure you put quotes around variables in your script (use
"$details"
instead of$details
), as this protects you from a whole class of bugs caused by spaces in file names. - You don't need to use
cat
to pass the content of a file toawk
. It's rare that you need to usecat
for this kind of thing in general, as most programs accept the name of a file in their arguments. If they don't, you can always useprogram < filename
rather thancat filename | program
. - The use of
ls
is redundant (and possibly prone to bugs caused by files with awkward names). It would be much better to usefor device in *.txt
; do ...`
- 确保在脚本中的变量周围加上引号(使用
"$details"
而不是$details
),因为这可以保护您免受由文件名中的空格引起的整类错误的影响。 - 您不需要使用
cat
将文件内容传递给awk
.cat
一般来说,您很少需要使用这种东西,因为大多数程序在它们的参数中接受文件名。如果他们不这样做,您始终可以使用program < filename
而不是cat filename | program
. - 的使用
ls
是多余的(并且可能容易出现由名称笨拙的文件引起的错误)。使用会好得多for device in *.txt
; 做...`
As a final point, be wary of getting trapped into thinking of one solution to your problem then asking how to implement it. It is much easier for others to come up with the best solution to the more general problem, based on their experience of various tools. In this case, the final answer is very different to the answer to your original question! I've left it below for now.
最后一点,请注意不要陷入思考问题的一种解决方案,然后询问如何实施它。其他人根据他们对各种工具的经验,为更普遍的问题提出最佳解决方案要容易得多。在这种情况下,最终答案与您原始问题的答案大不相同!我暂时把它留在下面。
Let me know if you don't have GNU awk and I'll update my answer.
如果您没有 GNU awk,请告诉我,我会更新我的答案。
I think that you might be looking for the paste
command
我认为您可能正在寻找paste
命令
By default, the two files will be separated by a tab character. To use something else, you can specify the -d
switch, for example -d,
would set the separator to a comma instead.
默认情况下,这两个文件将由制表符分隔。要使用其他东西,您可以指定-d
开关,例如-d,
将分隔符设置为逗号。
If you want only the first columns from each file, you can use paste with awk:
如果你只想要每个文件的第一列,你可以使用 awk 粘贴:
##代码##Assuming that the columns in your two files are separated by a simple delimiter (like a space), cut
would work too:
假设您的两个文件中的列由一个简单的分隔符(如空格)分隔,cut
也可以:
In light of the update to your question, if you already have the content inside two variables, you can use this command instead:
根据您的问题的更新,如果您已经将内容包含在两个变量中,则可以改用此命令:
##代码##Thanks to all who contributed in the comments.
感谢所有在评论中做出贡献的人。
回答by John B
You can use the getline
functionin awk
to read from a separate file and synchronize the fields:
您可以使用getline
函数inawk
从单独的文件中读取并同步字段: