我有一个文本文件,我想加载到配置单元。它在字符串列中有换行符,因此无法正确加载。从我在网上发现的文件需要进行预处理,并删除所有这些换行符。到目前为止,我已尝试过许多正则表达式,但无济于事。
这是文件:
/biz/1-or-8;5.0;"a bunch of
text
with some
linebreaks in between.";2016-11-03
/biz/1-or-8;2.0;"more
text
here.";2016-10-18
所需的输出应为:
/biz/1-or-8;5.0;"a bunch of text with some linebreaks in between.";2016-11-03
/biz/1-or-8;2.0;"more text here.";2016-10-18
我可以在记事本++中实现这一点,将其用作正则表达式:(\r\n^(?!\/biz\/))+
然而,当我使用sed运行该正则表达式时,它不起作用:
sed -e 's/(\r\n^(?!\/biz\/))+//g' original.csv > clean.csv
答案 0 :(得分:1)
如上所述,sed
不支持(?!\/biz\/)
等外观断言。
由于您的输入基本上是记录,因此awk
提供了一种方便的解决方案。
使用 GNU awk
或Mawk(需要支持多字符输入记录分隔符):
awk -v RS='/biz/' '$1=$1 { print RS $0 }' file
RS='/biz/'
按/biz/
将输入拆分为记录(保留变量RS
是输入记录分隔符,默认为\n
。)
$1=$1
看似无操作,但实际上重建手头的输入记录($0
),规范化任何记录内部的空白运行 - 包括换行符 - 每个单独一个空格,依赖awk
的默认字段拆分和输出行为。
$1=$1
用作模式(有条件),因此作业的结果决定了相关的操作({ ... }
)为手头的记录执行。/biz
- 赋值返回''
,它在布尔上下文中求值为false,因此跳过关联的块 { print RS $0 }
打印重建的输入记录,前缀为输入记录分隔符; print
会自动附加输出记录分隔符ORS
,默认为\n
。
注意:您的代码引用\r\n
,即Windows样式的CRLF换行符。由于您尝试使用sed
,我相信Windows上可用的Unix实用程序版本可以透明地处理CRLF。
如果您实际上在Unix平台上并且恰好正在处理源自Windows的文件,则需要做更多的工作。
答案 1 :(得分:0)
也许这可以帮到你;
sed -n '/^\s*$/d;$!{ 1{x;d}; H}; ${ H;x;s|\n\([^\/biz]\)| \1|g;p}'
测试;
$ sed -n '/^\s*$/d;$!{ 1{x;d}; H}; ${ H;x;s|\n\([^\/biz]\)| \1|g;p}' test
/biz/1-or-8;5.0;"a bunch of text with some linebreaks in between.";2016-11-03
/biz/1-or-8;2.0;"more text here.";2016-10-18
答案 2 :(得分:0)
diagnostic
不支持外观,sed
确实
perl
$ perl -0777 -pe 's/(\n^(?!\/biz\/))+//mg' original.csv
/biz/1-or-8;5.0;"a bunch oftextwith somelinebreaks in between.";2016-11-03
/biz/1-or-8;2.0;"moretexthere.";2016-10-18
选项会将整个文件作为单个字符串-0777
选项允许在多行字符串中使用m
个锚点注意,Unix系统中的行结尾不使用^$
,但如果您的输入确实有,请使用OP中指定的\r
。
使用不同的分隔符以避免必须转义\r\n
/
另一种方法是删除一对双引号之间的所有perl -0777 -pe 's|(\n^(?!/biz/))+||mg' original.csv
个字符
\n
$ perl -0777 -pe 's|".*?"|$&=~s/\n//gr|gse' ip.txt
/biz/1-or-8;5.0;"a bunch oftextwith somelinebreaks in between.";2016-11-03
/biz/1-or-8;2.0;"moretexthere.";2016-10-18
修饰符允许s
匹配多行,.*
修饰符允许使用表达式代替字符串替换e
允许对匹配的文字$&=~s/\n//gr
答案 3 :(得分:0)
awk
救援! (具有多字符RS支持)
$ awk -v RS='\n?^/' 'NF{$1=$1; print "/" $0}' file
或
$ awk -v RS='\n?^/' 'NF{$1="/"$1}NF' file
答案 4 :(得分:0)
创建文件
$ cat biz.awk
{ # read entire input to a string `f' (skips newlines)
f = f $0
}
END {
gsub("[^^]/biz/", "\n/biz/", f) # add a newline to all but the
# first /biz/
print f
}
和
$ cat file
/biz/1-or-8;5.0;"a bunch of
text
with some
linebreaks in between.";2016-11-03
/biz/1-or-8;2.0;"more
text
here.";2016-10-18
用法:
awk -f biz.awk file
答案 5 :(得分:0)
sed用于单个行上的简单替换,即全部。对于其他任何你应该使用awk。使用GNU awk进行多字符RS和RT:
$ awk -v RS='"[^"]+"' -v ORS= '{gsub(/\n+/," ",RT); print $0 RT}' file
/biz/1-or-8;5.0;"a bunch of text with some linebreaks in between.";2016-11-03
/biz/1-or-8;2.0;"more text here.";2016-10-18