>第二次在这里发帖。如果我在格式上犯了任何错误,我深表歉意。 我有一个文件,其中包含一个美国州及其各自的首都,旁边用逗号分隔。
Alabama,Montgomery
Alaska,Juneau
Arizona,Phoenix
Arkansas,Little Rock
California,Sacramento
Colorado,Denver
我正在尝试将州和城市分成两个单独的文件,并设法提出了这个,
for line in $(cat file);do
capital=$(echo $line | cut -d , -f2)
state=$(echo $line | cut -d , -f1)
echo $capital >> capitals
echo $state >> states
done
这段代码的问题在于,即使我将剪切分隔符设置为逗号,该程序似乎仍有空间作为包含空格的城市的分隔符(例如小石城(。
使用我上面的程序,我的大写文件包含,
Montgomery
Juneau
Phoenix
Little
Rock
Sacramento
Denver
请注意,小石城在两行中,而不是在同一行中。如何修改我的程序以使其在同一行中?我尝试将 IFS 设置为逗号,但当我这样做时,我的大写文件也包含状态。
Alabama
Montgomery
Alaska
Juneau
Arizona
Phoenix
Arkansas
Little Rock
California
Sacramento
Colorado
Denver
如果您同意awk
,请您尝试以下操作。
awk '
BEGIN{
FS=","
out_city="city_output_file"
out_state="state_output_file"
}
{
print $1 > (out_state)
print $2 > (out_city)
}
' Input_file
带bash
:
while IFS=, read -r state city;
do
echo "$state" >> "state_output_file"
echo "$city" >> "city_output_file"
done < "Input_file"
虽然awk
可以解决这个问题,但您还应该了解如何在 shell 脚本中读取文件并使用参数扩展来修剪每行中不需要的文本,以隔离状态和大写字母,并将每个文本写入各自的文件。
它是 shell 脚本的基本面包和黄油部分。(这里很容易(例如:
#!/bin/bash
states=${2:-states} ## states as 2nd argument (default "states")
capitals=${3:-capitals} ## capitals as 3rd argument (default "capitals")
:>$states ## truncate both files
:>$capitals
while read -r line || [ -n "$line" ]; do
echo "${line%,*}" >> "$states" ## trim line from right to 1st comma
echo "${line#*,}" >> "$capitals" ## trim line from left to 1st comma
done < "$1"
(注意:脚本从作为程序第一个参数提供的文件名读取,并写入状态和首都文件(可选(作为第二个和第三个参数提供(
示例输入文件
$ cat file
Alabama,Montgomery
Alaska,Juneau
Arizona,Phoenix
Arkansas,Little Rock
California,Sacramento
Colorado,Denver
使用示例
$ bash separate.sh file
生成的输出文件
国家:
$ cat states
Alabama
Alaska
Arizona
Arkansas
California
Colorado
资本:
$ cat capitals
Montgomery
Juneau
Phoenix
Little Rock
Sacramento
Denver
awk
会更快,但上面的脚本将比您每次迭代管道输出到cut
生成多个子壳的原始尝试效率高几个数量级。仔细查看,如果您有其他问题,请告诉我。
添加合并文件
我想您还希望在单独的行上为州和首都提供一个合并文件。只需为输出添加另一个文件,例如
#!/bin/bash
states=${2:-states} ## states as 2nd argument (default "states")
capitals=${3:-capitals} ## capitals as 3rd argument (default "capitals")
combined=${4:-combined} ## combined as 4th argument (default "combined")
:>$states ## truncate all files
:>$capitals
:>$combined
while read -r line || [ -n "$line" ]; do
echo "${line%,*}" >> "$states" ## trim line from right to 1st comma
echo "${line#*,}" >> "$capitals" ## trim line from left to 1st comma
printf "%sn%sn" "${line%,*}" "${line#*,}" >> "$combined"
done < "$1"
(注意:将|| [ -n "$line" ]
添加到while
循环条件将处理没有POSIX文件结尾的最后一行('n'
在最后一行的末尾((
生成的输出文件
组合的:
$ cat combined
Alabama
Montgomery
Alaska
Juneau
Arizona
Phoenix
Arkansas
Little Rock
California
Sacramento
Colorado
Denver
无需为输入的每一行创建六个子进程。如果输入文件变得非常大,这将花费大量的挂钟时间。我会做的
cut -d , -f2 file > capitals
cut -d , -f1 file > states
无需为输入的每一行创建六个子进程。如果输入文件很大,那么它很有用
awk -F ',' '{print $(NF-1)}' > capital file
awk -F ',' '{print $NF}' > states file