如何在Linux中替换大型单行文本文件中的字符串?
有些软件在处理之前会将整个输入文件加载到内存中。如果输入文件包含非常长的字符串,则如果内存不足以容纳整个字符串,软件可能会崩溃。
我们将探讨在Linux中更改非常大的单行文件中单个字符的方法。一些应用程序无法处理非常大的单行文件,因此我们将研究我们的选择。
目标文件
一些现代JavaScript框架将所有代码压缩到单个语句中。假设我们有一个名为original.js的JavaScript单行代码,其中包含错误。它调用了“fliter”而不是“filter”。我们将在下一节中纠正此错误。
使用tr和sed
我们可以使用tr将该行分成两部分,然后我们可以使用sed将第一部分替换为第二部分。
分割长行
我们通常使用sed -i替换单行,但是sed会尝试将整个文件加载到RAM中。为了克服这个问题,让我们将我们的行分成多个较小的行,然后将它们传递给sed。最后,将结果重新组合在一起。
在Linux中,默认情况下,行用
换行符分隔。在我们的例子中,
换行符被替换为
换行符并输入到sed中。我们必须选择不在我们想要更改的行中的元素。此外,替换后输出应该相对较短。
如果我们想将单行分成多行,我们可以使用一个名为tr的命令,它可以单独处理每个字母。例如,如果我们想用换行符替换每个空格,我们可以键入tr'' '
',其中n代表任意数量的空格。
要将;替换为
,使用以下命令:
命令
$ echo "This is line one;This is line two" | tr ";" "
"
输出
This is line one This is line two
如果我们的文档中包含任何换行符,我们应该将“;”替换为“
”和“
”替换为“;”。这样做将允许我们保持原始换行符序列不变。然后我们将运行tr ";" "
"; 将第一行转换为单个换行符序列,并运行tr "
" ";" 将第二行转换为单个换行符序列。
我们将向输入添加换行符,这意味着我们需要将t参数替换为反向参数。所以假设我们要将每个;替换为
,以及每个
替换为;。然后我们只需编写如下内容:
命令
$ echo "This is line one;This is line two" | tr ";
" "
;" | tr "
;" ";
"
输出
This is line one;This is line two
我们可以看到,我们的输入是相同的。
使用awk
除了sed之外,还有其他程序可以替换文件中的字符串。我们可以使用awk及其gsub函数执行这些步骤。这将是一个两步过程,用于设置awk的行分隔符并替换字符串。
更改行分隔符
我们可以用任何不是我们试图分割的字符串一部分的字符替换默认的换行符(
)。例如,如果我们想将输入分成单词,我们可以用下划线(_)替换换行符。
要在awk中使用不同的行分隔符,我们将在BEGIN块中将RS(记录分隔符)设置为所需的字符。例如,如果我们想使用分号作为我们的换行符分隔符,我们将设置RS=";”。让我们来看一个例子:
命令
$ echo "This is line one;This is line two" | awk 'BEGIN{RS=";"}{print}'
输出
This is line one This is line two
正如上一节中提到的,我们必须生成与输入匹配的结果。即使awk使用“;”字符分割行,结果也必须与原始输入匹配。我们可以看到awk的printf函数打印出原始输入中不存在的新行。
让我们改用printf函数,这样就不会添加换行符:
命令
$ echo "This is line one;This is line two" | awk 'BEGIN{RS=";"}{printf "%s", $0}'
输出
This is line oneThis is line two
我们可以看到,我们只缺少“;”字符。我们知道所有行都以行分隔符开头,除了第一行。因此,让我们在所有行之前添加“;”字符,除非它是第一行:
命令
$ echo "Thsi is line one;This is line two" | awk 'BEGIN{RS=";"}{ if (NR != 1) { printf "%c", RS } printf "%s", $0 }'
输出
This is line one;This is line two
我们使用NR变量来确定我们当前在输入文件的哪个位置,然后使用RS变量打印换行符。
替换字符串
我们已经了解了如何使用awk(和sed)使用任何非换行符字符将行分割成字段。现在让我们看看如何用另一个文本替换文本文档中的一行。
要使用awk从文件中删除一个单词,我们将使用gensub函数。此函数的工作方式类似于sed的替换命令。它采用两个参数;第一个是正则表达式,第二个是我们想要替换模式的内容。我们将使用上一示例中的相同代码来执行此操作。
我们将重复之前所做的操作。让我们将“.fliter()”替换为“.filter()”。
$ awk 'BEGIN{RS=";"} {
gsub("\.fliter\(", ".filter(")
if (NR != 1) {
printf "%c", RS
}
printf "%s", $0
}' < original.js > fixed.js
请注意,当我们转义字符时,sed之间存在差异。我们还需要转义“(”字符,并且需要使用两个反斜杠。
结论
我们研究了两种在极长的单行文本中替换字符串的方法。
我们已经了解了如何使用sed操作文件,但是我们也学习了如何使用awk操作文件。在这个例子中,我们使用这两个工具操作相同的输入。
数据结构
网络
关系数据库管理系统 (RDBMS)
操作系统
Java
iOS
HTML
CSS
Android
Python
C语言编程
C++
C#
MongoDB
MySQL
Javascript
PHP