扩展前一个here的问题。 (我喜欢问新问题,而不是编辑第一个问题。我可能是错的)
编辑:好的,我错了,我应该编辑第一个问题。我不好(所以问题是一门艺术,很难掌握)
我有一个csv文件,用半列作为字段分隔符。这是csv文件的摘录:
...;field;(:);10000(n,d);(:);field;....
...;field;123.12(b);123(a);123.00(:);....
这是所需的输出:
...;field;(:);(n,d) 10000;(:);field;....
...;field;(b) 123.12;(a) 123;(:) 123.00;....
我正在寻找一种解决方案,以便在每个字段中交换2种模式。
模式1:任意数字,带有可选的小数点(。)和可选的十进制数字
例如:1 / 1111.00 / 444444444.3 / 32 / 32.6666666 / 1.0 / ....
模式2:任何以左括号开头,后接一个或多个字符,以右括号结尾的字符串
例如:(n,a,p)/(:) /(llll)/(d)/(123)/(1; 2; 3)...
第一个问题中提供的解决方案适用于仅包含一列的简单文件。如果我在csv文件中尝试该解决方案,则会遇到多个故障。
因此,我尝试awk
类似的解决方案,(我认为)该解决方案更“面向列”。
我尝试过
awk -F";" '{print gensub(/([[:digit:].]*)(\(.*\))/, "\\2 \\1", "g")}' file
尽管我通过固定字段定界符(;),但“我的正则表达式交换”将在每个字段中成功。这是一个错误。
这是失败的一个例子
;(:);7320000(n,d);(:)
所需的输出-> ;(:);(n,d) 7320000;(:)
我的问题(最后):awk
在单列文件成功时为何失败。面对挑战的最佳工具是什么?
PS:我知道我不清楚。我有2个问题(英语,技术限制)。抱歉。
答案 0 :(得分:0)
好吧,当解析不带引号的简单分隔的文件时,通常awk可以解决:
awk -vFS=';' -vOFS=';' '{
for (i = 1; i < NF; i++) {
split($i, t, "(")
if (length(t[1]) != 0 && length(t[2]) != 0) {
$i="("t[2]" "t[1]
}
}
print
}' <<EOF
...;field;(:);10000(n,d);(:);field;....
...;field;123.12(b);123(a);123.00(:);....
EOF
但是,如果用引号括起来,则此操作将失败。分隔符;
位于值内...
;
for (i = 1; i < NF; i++)
行中的所有字段(
个字符(
的第一个字段的长度为非零,而第二个字段的长度也为非零(
)。print
被编辑。使用sed
和xargs
的解决方案,但您需要提前知道字段数:
{
sed 's/;/\n/g' |
sed 's/\([^(]\{1,\}\)\((.*)\)/\2 \1/' |
xargs -d '\n' -n7 -- printf "%s;%s;%s;%s;%s;%s;%s\n"
} <<EOF
...;field;(:);10000(n,d);(:);field;....
...;field;123.12(b);123(a);123.00(:);....
EOF
;
做一个换行符(
之前的字符和)
内的字符串替换字符串。;
作为分隔符与xargs和printf合并7行。答案 1 :(得分:0)
这可能对您有用(GNU sed):
sed -r 's/([0-9]+(\.[0-9]+)?)(\([^)]*\))/\3 \1/g' file
寻找一组数字(可能带有小数点),后跟一对括号,并以所需的方式在每行中全局重新排列它们。
答案 2 :(得分:0)
您的“问题”太长,混乱,并且包含太多无法解决的独立问题,但这是如何从任何sed提供的输入中获得所需的输出:
$ sed 's/\([0-9][0-9.]*\)\(([^)]*)\)/\2 \1/g' file
...;field;(:);(n,d) 10000;(:);field;....
...;field;(b) 123.12;(a) 123;(:) 123.00;....