在Txt文件中查找字符串,删除整行

时间:2021-09-26 18:27:07

I'm currently working with node.js to create an IRC bot. The bot allows users to add song links to a database. Each time someone submits a song, it is added to a new line of "shuffle.txt" as such:

我目前正在使用node.js创建一个IRC bot。机器人允许用户将歌曲链接添加到数据库。每当有人提交一首歌曲时,它就会被添加到新的“shuffle.txt”行中:

user1,The Beatles,Yesterday,(youtube link)
user2,The Rolling Stones,Angie,(youtube link)
user1,The Bealtes,Yellow Sumbarine,(youtube link)

Notice that user1 mistyped some information in their latest addition. I'm trying to make an UNDO command so that a user can delete their most recently entered line. I plan on doing this by finding the latest occurrence of their name in shuffle.txt and deleting the entire line that it's found on. Here's my message listener:

请注意,user1在最新添加的内容中输错了一些信息。我正在尝试制作UNDO命令,以便用户可以删除最近输入的行。我打算通过在shuffle.txt中查找最新出现的名称并删除它所找到的整行来做到这一点。这是我的消息监听器:

bot.addListener('message', function(from, to, message) {
    if (message.indexOf(config.prefix) == 0) {

        message = message.slice(1);
        var token = message.split(" ");

        if (token[0] == 'undo') {
              //find and delete
            }

    }
});

the user entering the command is stored as from

输入命令的用户存储为

I'm assuming I'll have to do something along the lines of this:

我假设我必须按照以下方式做一些事情:

var songList = fs.readFileSync('shuffle.txt', 'utf8');
var position = songList.indexOf(from);

if (position != -1) { //if 'from' found

  //find LAST occurrence of 'from'
  //get length from here to next occurrence of '\n'
  //substr(length + 1)

  fs.writeFile('shuffle.txt', songList, function(err) {
    if (err) {
      console.log (err);
    }

}

I'm new to JavaScript and this is my first time using node.js so I can use any help I can get! Thanks everyone.

我是JavaScript的新手,这是我第一次使用node.js,所以我可以使用任何帮助!感谢大家。

EDIT: I should also point out that I don't need help with the command recognition. I only need help with the finding/deleting portion. Cheers!

编辑:我还应该指出,我不需要命令识别方面的帮助。我只需要查找/删除部分的帮助。干杯!

2 个解决方案

#1


2  

Edit2: edited with a new solution.

Edit2:使用新解决方案进行编辑。

You could try this:

你可以试试这个:

fs.readFile('shuffle.txt', function read(err, data) {
    if (err) {
        throw err;
    }

    lastIndex = function(){
        for (var i = data_array.length - 1; i > -1; i--)
        if (data_array[i].match('user1'))
            return i;
    }()

    delete data_array[lastIndex];

});

Split file into lines, find the last line with a simple loop going backwards, remove the line using delete, then patch it back together.

将文件拆分为行,使用简单循环向后查找最后一行,使用delete删除行,然后将其重新修补。

demo

Also, you should not use readFileSync in node, as blocking node can be dangerous since it's single threaded.

此外,您不应该在节点中使用readFileSync,因为阻塞节点可能是危险的,因为它是单线程的。

#2


1  

This seems to work ok. It's self contained so you can just paste into a HTML file to see it run. Basically keep running a regular expression to match the whole line starting with the username passed. The whole line is returned ("gm" part of regular expression tells it to match a line at a time) as a string.

这似乎工作正常。它是自包含的,因此您只需粘贴到HTML文件中即可运行。基本上继续运行正则表达式以匹配从传递的用户名开始的整行。返回整行(正则表达式的“gm”部分告诉它一次匹配一行)作为字符串。

Then you just to a replace of that returned line (as string) within the data. Note that this assumes that line is unique in the text file. If you think people might have entered the same line a few times (but only want to remove the last one) then the 'non lazy' option whcih I've left uncommented is best. I haven't tested what happens if the line is first in the data or last.

然后你只需要替换数据中的返回行(作为字符串)。请注意,这假定该行在文本文件中是唯一的。如果你认为人们可能已经进入了同一行几次(但只想删除最后一行)那么我没有注释的“非懒惰”选项是最好的。我没有测试如果该行在数据中的第一个或最后一行会发生什么。

<html>
<head>
<script type="text/javascript">
var sData="user1,The Beatles,Yesterday,(youtube link)\nuser2,The Rolling Stones,Angie,(youtube link)\nuser1,The Bealtes,Yellow Sumbarine,(youtube link)\nuser3,The Rolling Stones,Angie,(youtube link)";

function replaceLastEntry(sText) {
  sNewData=sData;
  var re=new RegExp("^"+sText+".*$","gm"); // matches whole lines starting with sText 

  var lastIndex=-1;
  var i=0;
  var sMatch=re.exec(sData)!= null;
  while (sMatch!=null)
    {
    i++
    lastIndex=re.lastIndex;
    lastMatch=sMatch.toString(); // make note of last successful match - gives full line
    sMatch=re.exec(sData);
  }

  // at this point lastMatch contains the whole line which needs to be removed.
  // lastIndex is the string position of the character after the LAST string matched (ie the end of the matched line)
  // sNewData = sData.replace(lastMatch,""); // Lazy way - assumes the line is unique within the file

  // non-lazy way : locate the text by position returned and remove it
  sNewData = sData.substr(0, lastIndex-lastMatch.length-1) +   sData.substr(lastIndex);

  document.getElementById("Data").innerHTML=sData
  document.getElementById("NewData").innerHTML=sNewData
  document.getElementById("LastMatch").innerHTML=lastMatch
}

</script>
</head>


<body onload="replaceLastEntry('user1','newvalue')">
Data: <pre id="Data"></pre>
New Data:<pre id="NewData"></pre>
Last Match: <pre id="LastMatch"></pre>
</body>
</html>

hope this helps !

希望这可以帮助 !

#1


2  

Edit2: edited with a new solution.

Edit2:使用新解决方案进行编辑。

You could try this:

你可以试试这个:

fs.readFile('shuffle.txt', function read(err, data) {
    if (err) {
        throw err;
    }

    lastIndex = function(){
        for (var i = data_array.length - 1; i > -1; i--)
        if (data_array[i].match('user1'))
            return i;
    }()

    delete data_array[lastIndex];

});

Split file into lines, find the last line with a simple loop going backwards, remove the line using delete, then patch it back together.

将文件拆分为行,使用简单循环向后查找最后一行,使用delete删除行,然后将其重新修补。

demo

Also, you should not use readFileSync in node, as blocking node can be dangerous since it's single threaded.

此外,您不应该在节点中使用readFileSync,因为阻塞节点可能是危险的,因为它是单线程的。

#2


1  

This seems to work ok. It's self contained so you can just paste into a HTML file to see it run. Basically keep running a regular expression to match the whole line starting with the username passed. The whole line is returned ("gm" part of regular expression tells it to match a line at a time) as a string.

这似乎工作正常。它是自包含的,因此您只需粘贴到HTML文件中即可运行。基本上继续运行正则表达式以匹配从传递的用户名开始的整行。返回整行(正则表达式的“gm”部分告诉它一次匹配一行)作为字符串。

Then you just to a replace of that returned line (as string) within the data. Note that this assumes that line is unique in the text file. If you think people might have entered the same line a few times (but only want to remove the last one) then the 'non lazy' option whcih I've left uncommented is best. I haven't tested what happens if the line is first in the data or last.

然后你只需要替换数据中的返回行(作为字符串)。请注意,这假定该行在文本文件中是唯一的。如果你认为人们可能已经进入了同一行几次(但只想删除最后一行)那么我没有注释的“非懒惰”选项是最好的。我没有测试如果该行在数据中的第一个或最后一行会发生什么。

<html>
<head>
<script type="text/javascript">
var sData="user1,The Beatles,Yesterday,(youtube link)\nuser2,The Rolling Stones,Angie,(youtube link)\nuser1,The Bealtes,Yellow Sumbarine,(youtube link)\nuser3,The Rolling Stones,Angie,(youtube link)";

function replaceLastEntry(sText) {
  sNewData=sData;
  var re=new RegExp("^"+sText+".*$","gm"); // matches whole lines starting with sText 

  var lastIndex=-1;
  var i=0;
  var sMatch=re.exec(sData)!= null;
  while (sMatch!=null)
    {
    i++
    lastIndex=re.lastIndex;
    lastMatch=sMatch.toString(); // make note of last successful match - gives full line
    sMatch=re.exec(sData);
  }

  // at this point lastMatch contains the whole line which needs to be removed.
  // lastIndex is the string position of the character after the LAST string matched (ie the end of the matched line)
  // sNewData = sData.replace(lastMatch,""); // Lazy way - assumes the line is unique within the file

  // non-lazy way : locate the text by position returned and remove it
  sNewData = sData.substr(0, lastIndex-lastMatch.length-1) +   sData.substr(lastIndex);

  document.getElementById("Data").innerHTML=sData
  document.getElementById("NewData").innerHTML=sNewData
  document.getElementById("LastMatch").innerHTML=lastMatch
}

</script>
</head>


<body onload="replaceLastEntry('user1','newvalue')">
Data: <pre id="Data"></pre>
New Data:<pre id="NewData"></pre>
Last Match: <pre id="LastMatch"></pre>
</body>
</html>

hope this helps !

希望这可以帮助 !