^M (\r) 和 ^K (\v) 的命令行文本 find/replace
Command line text find/replace for ^M (\r) and ^K (\v)
我正在尝试编写一个 shell 脚本(除其他外)将替换 windows 行结尾 (^M
) 和垂直制表符 (^K
)用新线。 Sed
看起来像可以使用的工具,但我不太明白。我不明白为什么这行不通..
$ sed -i 's/^K/\n/g' article_filemakerExport.xml
sed: 1: "article_filemakerExport ...": command a expects \ followed by text
注意:我正在研究 mac。
以Windows行结束,你想删除^M(或\r
或回车return),但你想用换行符替换^K,它似乎。
我要使用的命令是 tr
,两次。
tr -d '\r' < article_filemakerExport.xml | tr '' '' > tmp.$$ &&
mv tmp.$$ article_filemakerExport.xml || rm -f tmp.$$
鉴于一个操作是删除,另一个是替换,我认为您不能将它们合并到一个 tr
调用中。如果您担心链接等问题,可以使用 cp tmp.$$ article_filemakerExport.xml; rm -f tmp.$$
您也可以使用 dos2unix
将 CRLF 转换为 NL 行结尾而不是 tr
。
注意tr
是纯过滤器;它只读取标准输入,只写入标准输出。它不直接读取或写入文件。
Actually, I need to replace both of these with a newline.
这更容易:调用 tr
即可完成工作:
tr '' '' < article_filemakerExport.xml > tmp.$$ &&
mv tmp.$$ article_filemakerExport.xml || rm -f tmp.$$
或者,如果您愿意:
tr '\r' '\n\n' < article_filemakerExport.xml > tmp.$$ &&
mv tmp.$$ article_filemakerExport.xml || rm -f tmp.$$
我认为 control-K 没有 \z
风格的符号,但我愿意学习其他方式(可能是垂直制表符,\v
)。
(在 Ed Morton 的提示处添加了 &&
和 || rm -f tmp.$$
命令。)
部分控制字符列表
C Oct Dec Hex Unicode Name
\a 07 7 07 U+0007 BELL
\b 10 8 08 U+0008 BACKSPACE
\t 11 9 09 U+0009 HORIZONTAL TABULATION
\n 12 10 0A U+000A LINE FEED
\v 13 11 0B U+000B VERTICAL TABULATION
\f 14 12 0C U+000C FORM FEED
\r 15 13 0D U+000D CARRIAGE RETURN
您可以在 Unicode 站点 (http://www.unicode.org/charts/PDF/U0000.pdf) 找到这些控制字符的完整集合。毫无疑问,还有许多其他可能的地方也可以看。
dos2unix <article_filemakerExport.xml | tr '35' '\n\n'
BSD (OS X) sed
解决方案,由 ANSI C-quoted bash strings:
协助
sed -i "" $'s/\r$/\\n/g; s/\v/\\n/g' article_filemakerExport.xml
注:
- BSD
sed
- 与 GNU sed
不同 - 需要 带有 -i
选项的参数;因此,为了表明应该创建 no 备份文件,必须传递一个 空字符串 (""
) - 见下文了解如何这解释了你得到的错误。
- 该命令将
\r\n
替换为 \n\n
而不是 \n
,这是我理解您想要的(要获得 \n
,只需将第二个替换字符串空;要替换 \r
,即使没有直接跟在 \n
后面,也要删除 \r
之后的 $
。
这是一个带有示例输入的概念证明:
$ sed $'s/\r$/\\n/g; s/\v/\\n/g' <<<$'one\vtwo\r\nthree\nfour'
one
two
three
four
(上面输出中的所有换行符都是\n
。)
- 需要一个 ANSI C 引号字符串 (
$'...'
) 来弥补 BSD sed 中对转义序列的支持不足:shell 创建所需的控制字符 ($'\v'
创建一个垂直制表符(^K
;$''
也可以),$'\r'
CR(^M
),$'\n'
换行符)并传递 结果文字到sed
.
\\n
导致文字 \
后跟文字换行符 - BSD sed
要求替换字符串中的文字换行符被 \
转义(并且不'支持转义码\n
).
至于为什么你的命令不起作用:
注意:看起来您的问题至少部分源于假设 BSD sed
与 GNU sed
的工作方式相同,不幸的是,情况并非如此: 有许多细微的和不那么细微的区别 - 请参阅
-i
选项缺少参数导致 sed
将您的 程序 解释为 -i
参数,并且您的 文件名作为程序。由于您的文件名以 a
开头,sed
看到了 a
(追加文本)命令,并在文件名的其余部分上窒息(因为它不是有效的 a
命令) .
- 即使修复缺少的
-i
选项参数也不会使命令工作,原因如上(简而言之:不支持 control-char.escape sequences),还有你试图将垂直制表符表示为字符串 ^K
(在 GNU sed
中你可以直接使用 \v
)。
我正在尝试编写一个 shell 脚本(除其他外)将替换 windows 行结尾 (^M
) 和垂直制表符 (^K
)用新线。 Sed
看起来像可以使用的工具,但我不太明白。我不明白为什么这行不通..
$ sed -i 's/^K/\n/g' article_filemakerExport.xml
sed: 1: "article_filemakerExport ...": command a expects \ followed by text
注意:我正在研究 mac。
以Windows行结束,你想删除^M(或\r
或回车return),但你想用换行符替换^K,它似乎。
我要使用的命令是 tr
,两次。
tr -d '\r' < article_filemakerExport.xml | tr '' '' > tmp.$$ &&
mv tmp.$$ article_filemakerExport.xml || rm -f tmp.$$
鉴于一个操作是删除,另一个是替换,我认为您不能将它们合并到一个 tr
调用中。如果您担心链接等问题,可以使用 cp tmp.$$ article_filemakerExport.xml; rm -f tmp.$$
您也可以使用 dos2unix
将 CRLF 转换为 NL 行结尾而不是 tr
。
注意tr
是纯过滤器;它只读取标准输入,只写入标准输出。它不直接读取或写入文件。
Actually, I need to replace both of these with a newline.
这更容易:调用 tr
即可完成工作:
tr '' '' < article_filemakerExport.xml > tmp.$$ &&
mv tmp.$$ article_filemakerExport.xml || rm -f tmp.$$
或者,如果您愿意:
tr '\r' '\n\n' < article_filemakerExport.xml > tmp.$$ &&
mv tmp.$$ article_filemakerExport.xml || rm -f tmp.$$
我认为 control-K 没有 \z
风格的符号,但我愿意学习其他方式(可能是垂直制表符,\v
)。
(在 Ed Morton 的提示处添加了 &&
和 || rm -f tmp.$$
命令。)
部分控制字符列表
C Oct Dec Hex Unicode Name
\a 07 7 07 U+0007 BELL
\b 10 8 08 U+0008 BACKSPACE
\t 11 9 09 U+0009 HORIZONTAL TABULATION
\n 12 10 0A U+000A LINE FEED
\v 13 11 0B U+000B VERTICAL TABULATION
\f 14 12 0C U+000C FORM FEED
\r 15 13 0D U+000D CARRIAGE RETURN
您可以在 Unicode 站点 (http://www.unicode.org/charts/PDF/U0000.pdf) 找到这些控制字符的完整集合。毫无疑问,还有许多其他可能的地方也可以看。
dos2unix <article_filemakerExport.xml | tr '35' '\n\n'
BSD (OS X) sed
解决方案,由 ANSI C-quoted bash strings:
sed -i "" $'s/\r$/\\n/g; s/\v/\\n/g' article_filemakerExport.xml
注:
- BSD
sed
- 与 GNUsed
不同 - 需要 带有-i
选项的参数;因此,为了表明应该创建 no 备份文件,必须传递一个 空字符串 (""
) - 见下文了解如何这解释了你得到的错误。 - 该命令将
\r\n
替换为\n\n
而不是\n
,这是我理解您想要的(要获得\n
,只需将第二个替换字符串空;要替换\r
,即使没有直接跟在\n
后面,也要删除\r
之后的$
。
这是一个带有示例输入的概念证明:
$ sed $'s/\r$/\\n/g; s/\v/\\n/g' <<<$'one\vtwo\r\nthree\nfour'
one
two
three
four
(上面输出中的所有换行符都是\n
。)
- 需要一个 ANSI C 引号字符串 (
$'...'
) 来弥补 BSD sed 中对转义序列的支持不足:shell 创建所需的控制字符 ($'\v'
创建一个垂直制表符(^K
;$''
也可以),$'\r'
CR(^M
),$'\n'
换行符)并传递 结果文字到sed
. \\n
导致文字\
后跟文字换行符 - BSDsed
要求替换字符串中的文字换行符被\
转义(并且不'支持转义码\n
).
至于为什么你的命令不起作用:
注意:看起来您的问题至少部分源于假设 BSD sed
与 GNU sed
的工作方式相同,不幸的是,情况并非如此: 有许多细微的和不那么细微的区别 - 请参阅
-i
选项缺少参数导致sed
将您的 程序 解释为-i
参数,并且您的 文件名作为程序。由于您的文件名以a
开头,sed
看到了a
(追加文本)命令,并在文件名的其余部分上窒息(因为它不是有效的a
命令) .- 即使修复缺少的
-i
选项参数也不会使命令工作,原因如上(简而言之:不支持 control-char.escape sequences),还有你试图将垂直制表符表示为字符串^K
(在 GNUsed
中你可以直接使用\v
)。