【问题标题】:I need to delete string from position X to position Y on each line in a text file我需要在文本文件中的每一行从位置 X 到位置 Y 删除字符串
【发布时间】:2014-08-15 01:59:25
【问题描述】:

我有一个巨大的平面文件 100K 记录,每个记录跨越 3000 列。在归档之前,我需要删除一段数据从起始位置 300 到位置 500。这是我存档之前需要擦除的数据的敏感部分。 我正在寻找一个 awk 或 sed 或任何可以为我解决问题的类似命令。

示例文件

003133780 MORNING GLORY DR                                        SOUTHAMPTON         PA18966780 MORNING GLORY DR    
0054381303 MADISON ST                                             RADFORD             VA241411303 MADISON ST         
00586728 CONESTOGA COURT                                          CHADDS FORD         PA1931728 CONESTOGA COURT      
1852921800 SAMER RD                                               MILAN               MI481601800 SAMER RD           
192717175 EVERGREEN CIRCLE                                        HENDERSONVILLE      TN37075175 EVERGREEN CIRCLE    
213673217 EAST BRANCH                                             LONGVIEW            TX75604217 EAST BRANCH         
2490423205 NOTTAGE LANE                                           FALLS CHURCH        VA220423205 NOTTAGE LANE       
249357344 BALOGH PLACE                                            LONGWOOD            FL32750344 BALOGH PLACE        
2502811224 WILFORD HOLLOW ROAD                                    VINTON              VA241791224 WILFORD HOLLOW ROAD
277634210 AMANDA CT                                               WHITEHOUSE          TX7579119726 COPPER OAKS DRIVE 
282482507 B ST.                                                   CHESAPEAKE          VA23324507 B ST.               

预期输出

003133780 MORNING GLORY DR                                        SOUTHAMPTON         PA780 MORNING GLORY DR    
0054381303 MADISON ST                                             RADFORD             VA1303 MADISON ST         
00586728 CONESTOGA COURT                                          CHADDS FORD         PA28 CONESTOGA COURT      
1852921800 SAMER RD                                               MILAN               MI1800 SAMER RD           
192717175 EVERGREEN CIRCLE                                        HENDERSONVILLE      TN175 EVERGREEN CIRCLE    
213673217 EAST BRANCH                                             LONGVIEW            TX217 EAST BRANCH         
2490423205 NOTTAGE LANE                                           FALLS CHURCH        VA3205 NOTTAGE LANE       
249357344 BALOGH PLACE                                            LONGWOOD            FL344 BALOGH PLACE        
2502811224 WILFORD HOLLOW ROAD                                    VINTON              VA1224 WILFORD HOLLOW ROAD
277634210 AMANDA CT                                               WHITEHOUSE          TX19726 COPPER OAKS DRIVE 
282482507 B ST.                                                   CHESAPEAKE          VA507 B ST.               

在这里,我删除了位置 89 和 95 之间的字符。 一个小改动,我还需要将改动后的内容写入同一个文件中。

以下是我目前的脚本。 我正在遍历所有文件,将它们分成最大行数为 20000 的文件,然后在归档之前从位置 X 和 Y 中删除字符。

ls -1 *.[tT][xX][tT] 中的当前文件名 做 回声$当前文件名 临时文件名=${当前文件名%%.*} awk -v A="$tempfilename" '{filename = A "Part" int((NR-1)/20000) ".txt";打印 >> 文件名}' $当前文件名 awk '{print substr($0,1,522) substr($0,953) >> 文件名}' $currentfilename mv $currentfilename $APP_ROOT/存档 完成

【问题讨论】:

  • 列 300 到 500,或字符 300 到 500?
  • 你确定它不是从 301 开始的吗?另外,如果它们是列,每列是如何分开的?是否愿意提供示例输入,即使只有 1 行?也可以上传到pastebin.com
  • 你的分隔符是什么?逗号还是制表符?

标签: unix awk sed textedit


【解决方案1】:

假设位置表示列,您可以使用cut 选择您想要的列。

cut -f 1-299,501-3000 CutMe.txt

如果您的数据由逗号而不是制表符分隔,请使用-d

cut -d, -f 1-299,501-3000 CutMe.txt

如果位置意味着字符,你可以用cut -c做同样的事情。

cut -c 1-299,501-3000 CutMe.txt

【讨论】:

  • 另外:cut -c 300-500 --complement,用于 GNU cut
  • 由于 cut 不需要它,您可能需要省略结尾 3000 以防万一行长并非总是如此。 OP 关于“位置”和“列”的说法不同,现在很明显“位置”表示“字符”,但“列”可能表示“字段”,在这种情况下会有超过 3000 个字符。
【解决方案2】:

假设“位置”意味着“字符”:

awk '{print substr($0,1,299) substr($0,501)}' file

如果没有,则编辑您的问题以添加一些代表性示例输入和预期输出(例如,5 行,每行 6 列,而不是数千行,数千列)。

【讨论】:

  • 谢谢埃德。你能帮我理解解决方案吗?如果我理解正确,它将 char 1 到 299,然后将 char 开头 501 附加到它,跳过 300 到 500。
【解决方案3】:

使用sed

sed -r -i.bak 's/(.{299}).{200}/\1/' file

-r 选项启用扩展正则表达式。如果您需要使其可移植,您可以通过转义大括号和花括号来删除该选项。 -i 选项进行就地更改。我已经添加了扩展名.bak 以防止出现任何混乱。如果您不需要维护原始备份,则可以将其删除。

对于解决方案,我们只捕获捕获组中的前 299 个字符,然后寻找接下来需要删除的 200 个字符。我们用我们捕获的组替换整条线。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-14
    • 1970-01-01
    • 1970-01-01
    • 2019-07-31
    • 2022-11-14
    • 2016-08-18
    相关资源
    最近更新 更多