Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.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
Linux 使用不同的delimted[再次更新]将delimted字段移动到换行符中_Linux_Shell_Unix_Awk - Fatal编程技术网

Linux 使用不同的delimted[再次更新]将delimted字段移动到换行符中

Linux 使用不同的delimted[再次更新]将delimted字段移动到换行符中,linux,shell,unix,awk,Linux,Shell,Unix,Awk,我有一个逗号分隔的txt文件,它必须只有五列,但有些行的列数超过了5列。 我想把第6到第10行移到一个新行,把第11到第15行移到一个新行,依此类推。 第6、11、16等列使用空格deleimert代替逗号 下面是input.txt 111 1, 2, 3, 4, 5 11 2, 13, 14, 15 5, 16 11, 17, 18, 19, 20 22, 23, 24, 25, 26 22, 27, 28, 29, 21 30, 31, 32, 3333 3, 34 111 1, 2, 3

我有一个逗号分隔的txt文件,它必须只有五列,但有些行的列数超过了5列。
我想把第6到第10行移到一个新行,把第11到第15行移到一个新行,依此类推。 第6、11、16等列使用空格deleimert代替逗号

下面是
input.txt

111 1, 2, 3, 4, 5
11 2, 13, 14, 15 5, 16 11, 17, 18, 19, 20
22, 23, 24, 25, 26 22, 27, 28, 29, 21 30, 31, 32, 3333 3, 34
111 1, 2, 3, 4, 5
11 2, 13, 14, 15 5, 16
11, 17, 18, 19, 20
22, 23, 24, 25, 26
22, 27, 28, 29, 21
30, 31, 32, 3333 3, 34
下面是
Output.txt

111 1, 2, 3, 4, 5
11 2, 13, 14, 15 5, 16 11, 17, 18, 19, 20
22, 23, 24, 25, 26 22, 27, 28, 29, 21 30, 31, 32, 3333 3, 34
111 1, 2, 3, 4, 5
11 2, 13, 14, 15 5, 16
11, 17, 18, 19, 20
22, 23, 24, 25, 26
22, 27, 28, 29, 21
30, 31, 32, 3333 3, 34
在这个问题的当前(第三个)版本中,我们需要计算四个逗号,然后再计算一个实体,后面跟一个空格(不是逗号),然后在该点添加一个换行符。如果是这种情况,则使用:

$ sed  's/\(\([^,]\+,\)\{4\}[[:space:]]\+[[:alnum:]]\+\)[[:space:]]/\1\n/g' input.txt
111 1, 2, 3, 4, 5
11 2, 13, 14, 15 5, 16
11, 17, 18, 19, 20
22, 23, 24, 25, 26
22, 27, 28, 29, 21
30, 31, 32, 3333 3, 34
如果您的
sed
支持
-r
标志(GNU),则可以稍微改进命令的外观:

sed -r 's/(([^,]+,){4}[[:space:]]+[[:alnum:]]+)[[:space:]]/\1\n/g' input.txt
在OSX上,
-r
标志不受
-E
支持,应改为:

sed -E 's/(([^,]+,){4}[[:space:]]+[[:alnum:]]+)[[:space:]]/\1\n/g' input.txt

此问题第二版的解决方案

从给出的示例中,每当列以空格而不是逗号结尾时,我们都需要插入一个换行符。如果是这样,那么:

$ sed 's/\>[[:space:]]/\n/g' input.txt
1, 2, 3, 4, 5
12, 13, 14, 15, 16
11, 17, 18, 19, 20
22, 23, 24, 25, 26
22, 27, 28, 29, 21
30, 31, 32, 33, 34
上面的工作原理是查找单词的结尾,
sed
表示为
\>
,后跟任何类型的空格。然后用换行符替换该空格。后面跟逗号的列将被单独保留

如果我们只想替换第一次出现的,则
sed
substitute命令的格式为
s/old/new/
,如果我们想替换所有此类出现的,则
s/old/new/g
。由于我们希望替换所有引用,因此使用
g
。在上面的命令中,“old”部分是
\>[[:space:]
,意思是一个单词的结尾后跟任何类型的空格。“new”部分只是表示换行符的
\n

sed
还允许在适当位置更改文件:

sed -i 's/\>[[:space:]]/\n/g' input.txt
-i
选项告诉
sed
将输入文件更改到位。运行此命令后,将更新
input.txt

尝试:

$ cat f1
1,2,3,4,5
12,13,14,15,16 11,17,18,19,20
22,23,24,25,26 22,27,28,29,21 30,31,32,33,34

$ awk '1' RS=' |\n' f1
1,2,3,4,5
12,13,14,15,16
11,17,18,19,20
22,23,24,25,26
22,27,28,29,21
30,31,32,33,34
用户更新的上述输入解决方案将不起作用

$ cat f2
1, 2, 3, 4, 5
12, 13, 14, 15, 16 11, 17, 18, 19, 20
22, 23, 24, 25, 26 22, 27, 28, 29, 21 30, 31, 32, 33, 34

$ awk '{gsub(/, /,",");gsub(/ /,"\n");gsub(/,/,", ")}1'  f2

OR

$ awk '{gsub(/[[:alnum:]] /,"&\n")}1' f2

1, 2, 3, 4, 5
12, 13, 14, 15, 16
11, 17, 18, 19, 20
22, 23, 24, 25, 26
22, 27, 28, 29, 21
30, 31, 32, 33, 34
回答以下评论

gsub(/, /,",")     # Substitute comma for comma + space

gsub(/ /,"\n")     # So now (field + space + field) is left, substitute space with newline  

gsub(/,/,", ")     # substitute comma space (as you requested in expected output) for comma (first argument)

我没有时间将下面的脚本从ksh转换为bash,我将此作为一种实践:

#!/bin/ksh
splitline() {
   echo $* | IFS=\, read f1 f2 f3 f4 f5
   # remove first space
   fx=${f5# }
   echo ${fx} | read f5a f5b
   echo "${f1},${f2},${f3},${f4}, ${f5a}"
   if [[ -n "${f5b}" ]]; then
      splitline ${f5b}
   fi
}

cat input.txt | while read line; do
   splitline $line
done

除了第5列和第6列之间的空格、第10列和第11列之间的空格等,
input.txt
中是否可能有任何空格?
tr''\n'
我可以看到您更新了input您的input.txt很奇怪:
1111、1123333
中的空格被视为数据的一部分,但第5列中的空格必须视为字段分隔符。您确定您的第五列不能有空格作为数据的一部分吗?当一行有5列以上时,您是否总是有5的复数?这将有助于使用IFS=的递归解决方案,并检查第五个字段中是否有空格format@GanzRicanz谢谢你的澄清。看一下修改后的答案。请解释一下
awk'{gsub(/,/,“,”);gsub(//,“\n”);gsub(/,/,“,”)}1'
如果列的值像
111,11 1123145,1
将输入更新为well@GanzRicanz:是,如果您的输入与第一个解决方案类似,则此操作将不起作用。