替换文件中的\ n \ t模式

时间:2015-05-19 18:23:00

标签: regex awk sed ksh

好的我有一个以管道分隔的记录集

我正在检查每行的分隔符数量,因为它们已经开始包括|在数据中(我们无法更改传入的文件)

使用一个很棒的awk将坏记录解析成一个坏文件进行处理时我们发现有些数据有一个新行符号(\ n)(后跟一个制表符(\ t))

我试过sed用\ t替换\ n \ t但是它总是用\ r \ n更改\ n \ t或替换所有\ n(文件是\ r \ n用于行结束)< / p>

是的,回答下面的一些问题...

文件可能大200+ mb

换行是虚假的数据(不是每一行......但是应该是痛苦的)

我试过了

sed ':a;N;$!ba;s/\n\t/\t/g' Clicks.txt >test2.txt

sed 's/\n\t/\t/g' Clicks.txt >test1.txt

样本记录

12345 | 876 | TESTDATA \ n
\ t \ t \ t \ tsome text | 6209 \ r \ n

想要 12345 | 876 | testdata \ t \ t \ t \ tsome text | 6209 \ r \ n

请帮助!!!

注意必须在KSH中(具体为MKS KSH)

我不在乎它是否是sed ..只需要纠正这个问题......

下面的几个解决方案会唤醒小数据或完成部分工作......

作为一个旁边,我已经开始玩删除所有换行,然后用carrige返回换行替换caraige返回..但不能完全得到它的工作

我已经尝试过TR,但由于它是单个字符,它只能解决部分问题

tr -d'\ n'test.txt 留下一个\ r \ n结束文件....

需要将其发送到\ r \ n(此系统上不存在dos2unix或unix2dos)

4 个答案:

答案 0 :(得分:3)

如果输入文件很小(因此您不介意处理它两次),您可以使用

cat input.txt | tr -d "\n" | sed 's/\r/\r\n/g'

编辑: 正如我现在应该知道的,你可以避免在任何地方使用猫。 我在UUOC中查看了我在SO中的旧答案,并仔细检查了tr使用中的可能文件名。正如Ed在他的评论中指出的那样,cat也可以在这里避免:

上面的命令可以通过

来改进
tr -d "\n" < input.txt | sed 's/\r/\r\n/g'

答案 1 :(得分:2)

目前还不清楚你要做什么但给出了这个输入文件:

$ cat -v file                                                
12345|876|testdata
        some text|6209^M

这是你要做的事情:

$ gawk 'BEGIN{RS=ORS="\r\n"} {gsub(/\n/,"")} 1' file | cat -v
12345|876|testdata      some text|6209^M

以上使用GNU awk进行多字符RS。或者任何awk:

$ awk '{rec = rec $0} /\r$/{print rec; rec=""}' file | cat -v
12345|876|testdata      some text|6209^M

上面的cat -v就是显示\r s(^M s)所在的位置。

答案 2 :(得分:1)

请注意,下面的解决方案将输入文件作为一个整体读入内存,这对大文件不起作用。
通常,Ed Morton's awk solution更好。

这是 POSIX兼容的sed解决方案

tab=$(printf '\t')
sed -e ':a' -e '$!{N;ba' -e '}' -e "s/\n${tab}/${tab}/g" Clicks.txt

使这个POSIX兼容的关键:

  • POSIX sed不会将\t识别为转义序列,因此文字标签 - 通过变量$tab,使用{{1}创建必须在脚本中使用。
  • POSIX tab=$(printf '\t') - 或者至少是BSD sed - 需要标签名称(例如sed:a a上面的) - 无论是暗示的还是显式的 - 用实际的换行符终止,或者通过在下一个ba选项中继续脚本来隐式终止,这是这里选择的方法。
  • -e是一个既定的Sed成语,简直就是&#34; slurps&#34;整个输入文件(使用循环首先将所有行读入其缓冲区)。这是在输入行中启用后续字符串替换的先决条件。
  • 请注意最后一个-e ':a' -e '$!{N;ba' -e '}'选项的option-argument是双引号字符串,以便对shell变量-e的引用扩展为 actual在Sed看到它们之前的标签。相比之下,$tab是POSIX sed自身识别的一个转义序列(在正则表达式部分,而不是替换字符串一部分)。

或者,如果您的shell支持ANSI C-quoted strings \n),则可以直接使用它们来生成所需的控制字符:

$'...'

注意最后sed -e ':a' -e '$!{N;ba' -e '}' -e $'s/\\n\t/\\t/g' Clicks.txt 选项的option-argument是ANSI C引用的字符串,以及 literal -e(这是一个转义序列<然后,必须将由POSIX Sed识别的em> 表示为\n。相比之下,\\n会在Sed看到它之前将$'...'扩展为实际标签。

答案 3 :(得分:0)

感谢大家提出的所有建议。看完所有答案之后..没有完成任务......经过一番思考......我想出了

tr -d '\n' <Clicks.txt | tr '\r' '\n' | sed 's/\n/\r\n/g' >test.txt
  1. 删除所有换行符
  2. 将所有回车转换为换行符
  3. 用替换回车换行符替换所有换行符
  4. 这可以在32mb文件上工作几秒钟。