繁体   English   中英

如何在 Bash 中将包含以逗号分隔的空格的两个字符串存储到两个单独的文件中

[英]How to store two strings which includes spaces separated by a comma into two separate files in Bash

第二次在这里发帖。 如果我的格式有任何错误,我深表歉意。 我有一个文件,其中包含美国 State 及其旁边用逗号分隔的各自首都。

Alabama,Montgomery
Alaska,Juneau
Arizona,Phoenix
Arkansas,Little Rock
California,Sacramento
Colorado,Denver

我试图将 state 和 city 分成两个单独的文件,并设法想出了这个,

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

请注意Little Rock如何位于两条不同的线而不是同一线。 如何修改我的程序以使其位于同一行? 我试过将 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 "%s\n%s\n" "${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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM