Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 在unix中使用sed格式化_Bash_Shell_Unix_Sed - Fatal编程技术网

Bash 在unix中使用sed格式化

Bash 在unix中使用sed格式化,bash,shell,unix,sed,Bash,Shell,Unix,Sed,我的输入文件的格式如下: 5470, 1875566222, "Antigua" 6, 1588552226, "Barbados 12, 1488899666, "Nicaragua" 这种模式延续了上千条记录 每3行实际上是一条记录。每个记录中的第二个值是一个ID。整个文件中只有这三个ID 我的目标是: a) 格式化此文件,使每个记录都在一行中(即) b) 正如您在上面的输出中所注意到的,我还需要删除国家名称上的双引号 c) 我想根据每条记录的第一个字段的值按降序对该文件进行排序 d) 如

我的输入文件的格式如下:

5470,
1875566222,
"Antigua"
6,
1588552226,
"Barbados
12,
1488899666,
"Nicaragua"
这种模式延续了上千条记录

每3行实际上是一条记录。每个记录中的第二个值是一个ID。整个文件中只有这三个ID

我的目标是:

a) 格式化此文件,使每个记录都在一行中(即)

b) 正如您在上面的输出中所注意到的,我还需要删除国家名称上的双引号

c) 我想根据每条记录的第一个字段的值按降序对该文件进行排序

d) 如果每个记录都有ID,则将其写入一个单独的文件中。因此,我将查看3个文件,每个文件都有一组具有相同ID的记录

对于UNIX脚本来说,这可能要求很多。但如果至少有一部分可以通过unixshell脚本实现,我将非常感激


提前感谢您的时间和帮助。

在这里使用awk更容易:

> awk 'NR%3==1{a=$0} NR%3==2{b=$0} NR%3==0{gsub(/"/, ""); print a b $0}' file
5470,1875566222,Antigua
5,1488899666,United Kingdom
6,1588552226,Barbados
12,1488899666,Nicaragua
15,1488899666,United States
编辑:在不同的文件中获取此输出:

awk 'NR%3==1{a=$0} NR%3==2{b=$0} NR%3==0{gsub(/"/, ""); p=a; sub(/,$/, ".txt", p); print a b $0 > p}' fil
对每个文件进行排序:

mkdir _tmp
for i in [0-9]*.txt; do sort -nk1,1r "$i" > _tmp/$i; done
使用
awk

awk '{gsub(/"/,x);printf "%s"(NR%3==0?RS:""),$1}' file
5470,1875566222,Antigua
6,1588552226,Barbados
12,1488899666,Nicaragua

如果要根据ID将输出重定向到多个文件:

awk 'NR%3==2 {f=$0+0} {gsub(/"/,x);printf "%s"(NR%3==0?RS:""),$1 > f".txt"}'

这应包括a、b和c部分

$ paste -d "" - - - < file | tr -d '"' | sort -t, -k1 -nr
5470,1875566222,Antigua
12,1488899666,Nicaragua
6,1588552226,Barbados

我同意awk最适合这样做:

awk -F'\"|,' '/[0-9]+/{printf "%s,", $1} /[a-zA-Z]+/{print $2}'

这与其他答案非常相似。我一开始就做了,但我现在就发布了,因为我喜欢答案有解释:

awk 'BEGIN{FS="[\",]" ;OFS=","}
     !(NR%3) {country=$2; print id, num, country}
     NR%3==1 {id=$1}
     NR%3==2 {num=$1}' file
   | sort -t"," -k1,1 -nr
解释
  • BEGIN{FS=“[\”,]“OFS=“,”}
    将字段分隔符设置为
    。输出字段分隔符设置为逗号
  • 现在它与表示记录数的
    NR
    一起使用。在这种情况下,行数为
  • !(NR%3){country=$2;print id,num,country}
    如果行是3的倍数(即NR/3的模数为0),则捕获值
    country
    并打印到整行
  • NR%3==1{id=$1}
    在3k+1行中,捕获id
  • NR%3==2{num=$1}
    在3k+2行中,捕获num
  • sort-t',“-k1,1-nr
    根据第一列(且仅第一列)对输出进行数字排序,并使用逗号
    作为列分隔符
试验
如果每次都要创建一个文件,请在
sort
之后进行管道排序,如下所示:
awk-F'{print>$3.dat'}'

对于这样的示例文件:

5470,
1875566222,
"Antigua"
6,
1588552226,
"Barbados
12,
1488899666,
"Nicaragua"
18,
148,
"Nicaragua"
它回来了

$ cat  Nicaragua.dat
18,148,Nicaragua
12,1488899666,Nicaragua

为什么要在将所有内容打印到单独的文件时进行排序?你说得对。但我仍然希望排序后,它被写入3个独立的文件。嗨,多班。当我在shell脚本中尝试此解决方案时,它会回复未找到的命令。有指针吗?您的系统上是否安装了
粘贴
。也许可以尝试分别运行管道的每个部分,以确定找不到哪个命令。
$ awk 'BEGIN{FS="[\",]" ;OFS=","} !(NR % 3) {print id, num, $2} NR%3==1 {id=$1} NR%3==2 {num=$1}' file | sort -t"," -k1,1 -nr
5470,1875566222,Antigua
12,1488899666,Nicaragua
6,1588552226,Barbados
$ awk 'BEGIN{FS="[\",]" ;OFS=","} !(NR % 3) {print id, num, $2} NR%3==1 {id=$1} NR%3==2 {num=$1}' file | sort -t"," -k1,1 -nr | awk -F, '{print > $3".dat"}'
5470,
1875566222,
"Antigua"
6,
1588552226,
"Barbados
12,
1488899666,
"Nicaragua"
18,
148,
"Nicaragua"
$ cat  Nicaragua.dat
18,148,Nicaragua
12,1488899666,Nicaragua