AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / unix / 问题 / 674676
Accepted
abacox
abacox
Asked: 2021-10-25 22:24:23 +0800 CST2021-10-25 22:24:23 +0800 CST 2021-10-25 22:24:23 +0800 CST

如何替换/删除新行(\n)?

  • 772

我busybox 1.27.2只能访问。

我目前正在处理一本包含超过 50 万字和 6,000 多页的字典(从带有 ghostscript 的 PDF 中提取并转换为纯文本)。在一个20MB .txt文件中。最初,这本词典中的每个单词都有一个前导->,以便于搜索单词。

我想要实现的是让它变得*nix友好。这意味着如果我这样做: grep -e '->myfancyword' ./dictionary.txt.

结果我应该得到:

->fancyword: This is a very fancy word. *Definition going on for more than 6 lines*

这很容易通过去除所有换行符来完成,\n因此每个单词都将在很长的一行中包含其所有定义,这没关系。我可以用所有替换\n,tr -d '\n'然后通过它的输出,sed 's/->/\n->/g'所以我将在一行中得到所有单词的定义。即使在这个巨大的文档上,它也可以在不到 5 秒的时间内完成。

我几乎得到了我想要的结果,但并不完美。我可以做到这一点grep -e '->word' ./dictionary.txt并得到这个词的完整定义。但它在外观上并不完美。

我对输出不满意的原因是因为原始 pdf 被格式化为打印在A4页面上,这意味着当有一个长单词时,它被切掉了。像这样:

例如

->word: This is a defini-
tion.

如果我使用以前的工作流程处理文件,我得到:->word: This is a defini- tion.当 grepping 所需的单词时。

到目前为止,我设法完成的是:

  1. 输入
->firstword: This is a defini-
tion.
->secondword: This is a second defini-
tion.
  1. 应用 tr -d '\n' < ./dictionary.txt > ./dictionary2.txt

  2. 输出是:

->firstword: This is a defini- tion. ->secondword: This is a second defini- tion.
  1. 跑了:sed -e 's/->/\n->/g' ./dictionary2.txt

  2. 结束于:

输出

->firstword: This is a defini- tion.
->secondword: This is a second defini- tion.

在进行第二步之前,我想删除破折号和换行符 ( -\n) 以将所有切碎的线“连接”在一起。

所以,我的问题是:如何替换/删除行尾包含破折号-和换行符\n( -\n) 的特定字符串?

我喜欢得到的是:

输出(请检查破折号和空格(- )不再存在)

->firstword: This is a definition.
->secondword: This is a second definition.

谢谢你。

编辑:

这是PDF文件的页面:


     ->abigeato. (Del lat. abigeatus). 1. m. Am. Hurto de ganado.
     ->abigeo. (Del lat. abigeus). 1. m. Am. Ladrón de ganado.
     ->abigotado, da. 1. adj. bigotudo.
     ->abinar. 1. tr. rur. y vulg. Binar la tierra.
     ->abintestato. (De ab intestato). 1. m. Der. Procedimiento judicial sobre herencia y
   adjudicación de bienes de quien muere sin testar.
     ->abiogénesis. (De a-2, bio- y -génesis). 1. f. Producción hipotética de seres vivos par-
   tiendo de materia inerte. 2. f. Bioquím. síntesis abiótica.
     ->abiótico, ca. 1. adj. Biol. Se dice del medio en que no es posible la vida.  V. síntesis
   abiótica
     ->abipón, na. 1. adj. Se dice del individuo de un pueblo amerindio que habitaba cerca del
   Paraná. U. t. c. s. 2. adj. Perteneciente o relativo a los abipones. 3. m. Lengua de la familia
   guaicurú hablada por los abipones.
     ->abisagrar. 1. tr. Clavar o fijar bisagras en las puertas y sus marcos, o en otros objetos.
     ->abisal. (Del lat. abyssus). 1. adj. abismal (|| perteneciente al abismo). 2. adj. Se dice de
   las zonas del mar profundo que se extienden más allá del talud continental, y corresponden a
   profundidades mayores de 2000 m. 3. adj. Perteneciente o relativo a tales zonas.
     ->abiselar. 1. tr. biselar.
     ->abisinio, nia. 1. adj. Natural de Abisinia, hoy Etiopía. U. t. c. s. 2. adj. Perteneciente o re-
   lativo a este país de África. 3. m. Lengua abisinia.  V. rito abisinio
     ->abismado, da. (Del part. de abismar). 1. adj. Dicho de una persona, de su expresión, de
   su gesto, etc.: Ensimismados, reconcentrados. 2. adj. Heráld. Dicho de una pieza del escudo:
   Puesta en el abismo.
     ->abismal (1).  (Del ár. hisp. almismár, y este del ár. clás. mismar). 1. m. Cada uno de los
   clavos con que se fijaba en el asta el hierro de la lanza.abismal2. 1. adj. Perteneciente o re-
   lativo al abismo. 2. adj. Muy profundo, insondable, incomprensible.
     ->abismar. 1. tr. Hundir en un abismo. U. t. c. prnl. 2. tr. Confundir, abatir. U. t. c. prnl. 3.
   prnl. Entregarse del todo a la contemplación, al dolor, etc. 4. prnl. Am. sorprenderse (|| con-
   moverse con algo imprevisto o raro).
     ->abismático, ca. 1. adj. abismal2.
     ->abismo. (Quizá del lat. vulg. *abyssimus, der. de abyssus, y este del gr. , sin fondo). 1.
   m. Profundidad grande, imponente y peligrosa, como la de los mares, la de un tajo, la de una
   sima, etc. U. t. en sent. fig. Se sumió en el abismo de la desesperación. 2. m. infierno (|| lugar
   de castigo eterno). 3. m. Cosa inmensa, insondable o incomprensible. 4. m. Diferencia
   grande entre cosas, personas, ideas, sentimientos, etc. 5. m. Heráld. Punto o parte central
   del escudo. 6. m. Nic. Maldad, perdición, ruina moral.

这是在使用 ghostscript 完成提取后对常规文本进行 grepping 时得到的结果(仅使用 dos2unix 处理):


grep -e '->abiog' ./rae-dos2unix.txt
     ->abiogénesis. (De a-2, bio- y -génesis). 1. f. Producción hipotética de seres vivos par-

这是在文本上完成前面的步骤(1-4)时,当我得到:


grep -e '->abiog' ./rae-una-linea.txt
->abiogénesis. (De a-2, bio- y -génesis). 1. f. Producción hipotética de seres vivos par-   tiendo de materia inerte. 2. f. Bioquím. síntesis abiótica.     

text-processing busybox
  • 2 2 个回答
  • 397 Views

2 个回答

  • Voted
  1. Best Answer
    cas
    2021-10-26T20:21:48+08:002021-10-26T20:21:48+08:00

    这在 perl 中相当容易。perl 的-0选项告诉它使用 NUL 字符而不是换行符作为输入记录分隔符,因此,除非输入中有 NUL 字符,否则它将把整个输入文件视为一条记录。即使有 NUL 字符,它也会继续处理后续记录,与第一个相同。

    注意:这确实意味着整个输入文件必须适合内存 - 在具有 16GB 或更多 RAM 的现代系统上,这不太可能成为问题。在 RAM 不足但交换空间足够的旧系统上,它仍然可以工作,但速度会慢得多。

    $ cat input.txt
    ->firstword: This is a defini-
    tion.
    ->secondword: This is a second defini-
    tion.
    
    $ perl -0 -p -e 's/-\s*\n//g' input.txt 
    ->firstword: This is a definition.
    ->secondword: This is a second definition.
    

    这将删除每个连字符序列,后跟零个或多个空格字符(\s,见下文),后跟换行符(\n)。

    \s*正则表达式的一部分用于匹配可能位于行尾的尾随空白字符 - 根据我的经验,文本行带有尾随空格是很常见的(而且它们很难被发现,因为它们不是打印字符,即不可见)。或者,使用 *(零个或多个空格字符) 或[ \t]*(零个或多个空格或制表符) 或\h*(零个或多个水平空白字符) 而不是\s*.

    来自man perlre:

    被视为空白的字符集是 Unicode 所称的“模式空白”,即:

    U+0009 CHARACTER TABULATION
    U+000A LINE FEED
    U+000B LINE TABULATION
    U+000C FORM FEED
    U+000D CARRIAGE RETURN
    U+0020 SPACE
    U+0085 NEXT LINE
    U+200E LEFT-TO-RIGHT MARK
    U+200F RIGHT-TO-LEFT MARK
    U+2028 LINE SEPARATOR
    U+2029 PARAGRAPH SEPARATOR
    

    笔记:

    1. -字符并不是唯一可能使用的“连字符”或“破折号”字符。维基百科的页面列出了 unicode连字符和破折号字符。幸运的是,perl 具有良好的 unicode 处理能力,因此可以重写单行代码以使用\p{Dash}(or \p{Pd}) 而不是-匹配所有破折号类别字符:
    $ perl -0 -p -e 's/\p{Dash}\h*\n//g' input.txt 
    ->firstword: This is a definition.
    ->secondword: This is a second definition.
    

    但是,这会将 em-dashes 视为与连字符相同的处理(因此将删除行尾的 em-dash,与连字符相同)......并且使用 em-dashes 而不是括号并不少见. 如果您不介意有关“连字符”被弃用的警告消息,您可以使用\p{Hyphen}代替。\p{Dash}或者,您可以使用仅包含要视为连字符的 unicode 代码点的括号表达式 - 例如

        perl -0 -p -e 's/[\N{U+002D}\N{U+00AD}\N{U+2010}\N{U+2011}]\h*\n//g' input.txt
    
    1. 我建议不要让每个单词定义都以->. 这将使使用 grep 搜索单词变得不必要的尴尬 - 搜索字符串必须被引用(因为>shell 用于重定向的 )并在前面--(因为-,否则 grep 会将您的搜索模式视为如果您的意思是它们是选项)。例如,您将无法做到:

       grep ^firstword: dictionary.txt
      

      相反,您必须这样做:

       grep -- '^->firstword:' dictionary.txt
      

    举个更好的例子,我使用tesseract-ocr从您的图像中提取了文本,并通过 perl one-liner 版本运行它,该版本还删除了所有不跟在后面的换行符->:

    $ cat input2.txt 
    ->abigeato. (Del lat. abigeatus). 1. m. Am. Hurto de ganado.
    ->abigeo. (Del lat. abigeus). 1. m. Am. Ladrén de ganado.
    ->abigotado, da. 1. adj. bigotudo.
    ->abinar. 1. tr. rur. y vulg. Binar la tierra.
    ->abintestato. (De ab intestato). 1. m. Der. Procedimiento judicial sobre herencia y
    adjudicacion de bienes de quien muere sin testar.
    Eiiftiénesis. (De a-2, bio- y -génesis). 1. f. Produccién hipotética de seres vivos par-
    tiendo de materia inerte. 2. f. Bioquim. sintesis abistica,
    ->abidtico, ca. 1. adj. Biol. Se dice del medio en que no es posible la vida. V. sintesis
    abidtica
    ->abipon, na. 1. adj. Se dice del individuo de un pueblo amerindio que habitaba cerca del
    Parana. U. t.c. s. 2. adj. Perteneciente o relativo a los abipones. 3. m. Lengua de la familia
    guaicurt hablada por los abipones.
    ->abisagrar. 1. tr. Clavar o fijar bisagras en las puertas y sus marcos, 0 en otros objetos.
    ->abisal. (Del lat. abyssus). 1. adj. abismal (|| perteneciente al abismo). 2. adj. Se dice de
    las zonas del mar profundo que se extienden mas alla del talud continental, y corresponden a
    
    $ perl -0 -p -e 's/[\N{U+002D}\N{U+00AD}\N{U+2010}\N{U+2011}]\h*\n//g; s/\n+(?!->)//g' input2.txt
    ->abigeato. (Del lat. abigeatus). 1. m. Am. Hurto de ganado.
    ->abigeo. (Del lat. abigeus). 1. m. Am. Ladrén de ganado.
    ->abigotado, da. 1. adj. bigotudo.
    ->abinar. 1. tr. rur. y vulg. Binar la tierra.
    ->abintestato. (De ab intestato). 1. m. Der. Procedimiento judicial sobre herencia yadjudicacion de bienes de quien muere sin testar.Eiiftiénesis. (De a-2, bio- y -génesis). 1. f. Produccién hipotética de seres vivos partiendo de materia inerte. 2. f. Bioquim. sintesis abistica,
    ->abidtico, ca. 1. adj. Biol. Se dice del medio en que no es posible la vida. V. sintesisabidtica
    ->abipon, na. 1. adj. Se dice del individuo de un pueblo amerindio que habitaba cerca delParana. U. t.c. s. 2. adj. Perteneciente o relativo a los abipones. 3. m. Lengua de la familiaguaicurt hablada por los abipones.
    ->abisagrar. 1. tr. Clavar o fijar bisagras en las puertas y sus marcos, 0 en otros objetos.
    ->abisal. (Del lat. abyssus). 1. adj. abismal (|| perteneciente al abismo). 2. adj. Se dice delas zonas del mar profundo que se extienden mas alla del talud continental, y corresponden a
    

    我仍然建议->从最终输出文件中删除该序列。在处理文本时它是一个有用的标记,但之后会出现问题。


    @zevzek 的评论解决了“使用大量 RAM”的问题。不使用 NUL 作为输入记录分隔符,而是使用->分隔符。这使得 perl 脚本一次只能读取一个单词定义,而不是一次读取整个文件。这将使它在输入文件非常大的情况下运行得更快,因为它不会使用所有可用的 RAM 并导致系统交换。

    需要对脚本进行其他更改,因为我们现在将标记新单词定义开头的字符序列视为先前定义的结尾。具体来说,我们现在需要:

    • 将命令行选项-p(始终输出当前记录)更改为-n(仅在我们告诉它时输出当前记录)。
    • 删除行尾字符(perl 的chomp()函数就是这样做的)
    • 检查输入记录是否为空或仅包含空格,因为现在在第一个实际记录“abigeato”之前会有一个假想的空记录,我们不想打印出来。(为什么会突然出现一个虚构的空记录?因为->now 表示记录的结束,而不是新记录的开始。in 是上一个(空)记录和新的“abigeato”记录之间的分隔符->)->abigeato
    • 使用“->”和换行符打印修改后的记录。

    总之,这些将改变最终的单线:

    $ perl -0 -p -e 's/[\N{U+002D}\N{U+00AD}\N{U+2010}\N{U+2011}]\h*\n//g;
                     s/\n+(?!->)//g' input2.txt
    

    对此:

    perl -n -e 'BEGIN { $/="->" };
                chomp;
                next if m/^\s*$/;
                s/[\N{U+002D}\N{U+00AD}\N{U+2010}\N{U+2011}]\h*\n//g;
                s/\n+//g;
                print "->$_\n"' input2.txt
    

    此版本的输出与原始版本相同,只是最终输出行保证以换行符 ( \n) 结束。原版并没有保证这一点,实际上它通过删除所有没有跟随的换行符来阻止它->。这是一个免费的奖励,因为从技术上讲,如果每一行都以\n.... 结尾,则文件只是 unix 中的文本文件。大多数情况下,这无关紧要(至少,对于标准文本处理工具的现代版本而言) ,但如果“文本文件”的最后一行不以 . 结尾,则某些程序无法正确处理它\n。

    (顺便说一句,可以通过添加一个 END 块将换行符添加回输出的末尾来修复原始内容END { print "\n" }:)

    $/是一个定义输入记录分隔符的 perl 变量(有关 perl 的预定义/特殊/控制变量的详细信息,请参阅man perlvar),类似于. 以前,我使用 perl 的选项将其设置为 NUL 字符(有关 perl 的命令行选项的详细信息,请参阅)。RSawk-0man perlrun

    BEGIN语句在脚本的开头发生一次,在while(<>) { ..... }使用 perl-p或-n选项引​​起的隐式循环之前和之外(这使得 perl 的行为有点像超级动力sed或sed -n分别)。类似地,END在所有输入都被读取和处理之后,一个语句在脚本结束时发生一次。

    • 2
  2. Philippos
    2021-10-26T04:14:03+08:002021-10-26T04:14:03+08:00

    N;P;D我建议使用以下模式在单个脚本中执行此操作:

    sed -e ':loop' -e '$!N;/\n->/!s/-*\n/ /;tloop' -e 'P;D'
    

    您循环添加 'N'ext 行并使用可选的破折号 ( s/-*\n/ /) 删除换行符,直到新行以 . 开头->。

    • 1

相关问题

  • grep 从 $START 到 $END 的一组行并且在 $MIDDLE 中包含匹配项

  • 重新排列字母并比较两个单词

  • 在awk中的两行之间减去相同的列

  • 多行文件洗牌

  • 如何更改字符大小写(从小到大,反之亦然)?同时[重复]

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve