如何从文件 [shell] 中某些特定行的末尾删除 \n?

How to delete \n from the end of some particular lines in file [shell]?

在 Redhat 中,我有 file.csv 具有以下数据:

170033101;20170302;;;"Free text 1"
170033101;20170302;;;"Free text 2"
170033101;20170302;;;"Free 
text 3"
170033101;20170302;;;"Free text 4"

我想在从文件中删除错误的 \n 后创建另一个更正文件 (Correct_file.csv),如下所示:

170033101;20170302;;;"Free text 1"
170033101;20170302;;;"Free text 2"
170033101;20170302;;;"Free text 3"
170033101;20170302;;;"Free text 4"

我的解决方案:

我制作了下面的 shell 脚本来查找那些不以 170 开头的行之前的行,然后创建 sed.txt 每个错误的行都有一个 sed 行来替换 \ n 与 space.

我无法执行 sed 命令或 tr 命令根据行号删除特定行

我的脚本:

>sed.txt;
for i in `grep -nv '^[1706]' |cut -f 1 -d \:`
do
if [ $i -eq 1 ]
then
continue
else
j=`expr $i - 1`
echo $j"s/\n//" >>sed.txt
fi
done
sed -f sed.txt  >

我调用脚本并传递 2 个参数 1- 旧文件 2- 新更正文件,新文件与旧文件完全一样,没有更正。

sed returns 新字符串,因此您不需要 echo 它。简称为 sed .. >> data.txt

下面的 sed 语句会将一行末尾的新行替换为空。您只需要传递要翻译的行

sed ':a;N;$!ba;s/\n//g' <LINE INPUT>

如果你给它传递一个文件,它会循环读取整个文件,并用 space.

替换换行符

你可以使用这个sed:

sed '/^170/{:loop; N;/\n170/{P;D;t}; s/\n//g;b loop}' file

输入:

$ cat file
170033101;20170302;;;"Free text 1"
170033101;20170302;;;"Free text 2"
170033101;20170302;;;"Free 
text 3"
170033101;20170302;;;"Free 
text 
4"

测试:

$ sed '/^170/{:loop; N;/\n170/{P;D;t}; s/\n//g;b loop}' file > correct_file.csv
170033101;20170302;;;"Free text 1"
170033101;20170302;;;"Free text 2"
170033101;20170302;;;"Free text 3"
170033101;20170302;;;"Free text 4"

当我想使用 \n 时,我更喜欢简单的 perl 而不是 sed:

$ cat file1
170033101;20170302;;;"Free text 1"
170033101;20170302;;;"Free text 2"
170033101;20170302;;;"Free
text 3"
170033101;20170302;;;"Free text 4" 

$ perl -pe 's/[^"]\n/ /g' file1
170033101;20170302;;;"Free text 1"
170033101;20170302;;;"Free text 2"
170033101;20170302;;;"Free text 3"
170033101;20170302;;;"Free text 4"

这个 perl oneliner 用单个 space 替换每个新行 \n 后面没有引号 "

PS:您可以在命令末尾添加 >newfile 以将 "corrected" 输出发送到 newfile 或者您甚至可以编辑当前文件使用 -i perl 开关放置。

您可以使用此 awk 命令,该命令根据行是否以 " 结尾的事实起作用:

awk '!/"$/{p=[=10=]; next} p!=""{[=10=] = p [=10=]; p=""} 1' file

170033101;20170302;;;"Free text 1"
170033101;20170302;;;"Free text 2"
170033101;20170302;;;"Free text 3"
170033101;20170302;;;"Free text 4"

尝试跟随 awk 一次。

awk '{printf("%s%s",[=10=] !~ /^[0-9]+/?"":(NR>1?RS:""),[=10=])} END{print ""}'  Input_file

检查此处是否有任何行不是从数字开始,然后通过 RS(记录分隔符)在那里打印新行,确保它不应该出现在第一行,否则什么也不打印。在 awk 打印 NULL 的 END 部分,最后将打印一个新行。