【问题标题】:Get into a line from a text file and edit it从文本文件中进入一行并编辑它
【发布时间】:2013-01-24 13:01:19
【问题描述】:

假设我的文本文件中有这一行,格式如下。

"Title:Author:Price:QtyAvailable:QtySold"

我的文本文件的内容如下所示

 Hello World:Andreas:10.50:10:5
 Lord Of The Rings:Duke:50.15:50:20
    (some other records...)

1) 用户输入作者和标题。

2) 如果程序找到作者+标题,它会要求用户更新任何可用的字段(对于这种情况,标题、作者、价格等。

3) 例如,我想更新 Hello World 书的价格。

4) 如何让程序提取Hello World 行的内容,并进入10.50 以替换书的价格? (假设图书的新价格将由用户输入决定)

希望得到我的答复。 提前感谢那些提供帮助的人!

【问题讨论】:

  • 你可以用 sed 来做,但你为什么要用 shell 脚本来做呢?对于相当于 CRUD 应用的内容来说,这是一个糟糕的选择。
  • 到目前为止你做了什么?问题是什么?
  • @Kent 我目前还没有做任何事情,因为我不知道从哪里开始。
  • 同意 frankc;这在“真正的”编程语言中会容易得多——我个人会使用 Python。 (我会使用一个小型数据库,例如 SQLite。)
  • 在学习 Unix shell 时,要学习的最重要的事情之一是识别不应在 shell 中解决的问题,因为它们需要更复杂的编程语言的力量。你所描述的任务肯定在这条线的另一端。 (也就是说,尝试在 shell 中做这件事,作为一种练习,也许会教你为什么这是一项如此重要的技能。)

标签: linux bash shell edit


【解决方案1】:

您可以像这样使用带有可变参数的 sed:

# book title:author to be searched
BOOK="Hello World:Andreas"

# price to be updated
PRICE=11.25

# search and update with original backed up with .bak extension
sed -i.bak 's/\('"$BOOK"'\):[^:]*:/\1:'"$PRICE"':/' file.txt

说明:

如果你在 sed 命令中填入 shell 变量,它将如下所示:

sed 's/\(Hello World:Andreas\):[^:]*:/\1:11.25:/'

匹配

"$BOOK"                 # match literal text i.e. Hello World:Andreas
\($BOOK\)               # group this text to be back referenced later
:                       # match literal :
[^:]*                   # match 0 or more characters until : is found
:                       # match a :

替换

\1                      # group # 1 i.e. Hello World:Andreas
:                       # a literal :
$PRICE                  # fill in the new price
:                       # literal :                   

本质上,这个 sed 命令正在查找具有 Hello World:Andreas: 后跟 某个价格值 的文本,然后是另一个 :。一旦找到此模式,它将用反向引用#1(即Hello World:Andreas)替换它,后跟:,然后输入新的价格值和冒号:

编辑:强烈建议您阅读一些 sed 教程,但是根据您的评论,我正在为您提供更新数量的命令:

# book title:author to be searched
BOOK="Hello World:Andreas"

# quantity to be updated
QTY=18

# search and update with original backed up with .bak extension
sed 's/^\('"$BOOK"'\):\([^:]*\):[^"]*:/\1:\2:'"$QTY"':/'

【讨论】:

  • 您好,感谢您的解决方案,我必须同意其他人的意见,在询问之前我必须自己做,但是这个问题已经困扰我很长时间了,我仍然没有对如何处理它的一点想法。
  • 嗨,anubhava,请注意解释 sed -i.bak 's/('"$BOOK"'):[^:]*:/\1:'"$PRICE"' 的行: /' 对我来说,它是如何工作的?谢谢
  • 请务必在我的回答中添加一些解释。
  • 嗨,我真的不明白。我需要更多的例子来让我更好地了解这些符号是如何工作的。好的,假设我想要更新我的标题呢?或我的可用数量。我该怎么做呢?
  • 嗯,您似乎不接受我的回答,它对您不起作用吗?无论如何,我更新了我的答案,告诉你如何编辑数量。请允许我这样说Once you spend some time in understanding regex and sed, now only you will be able to answer these questions of updating individual fields yourself, you will start helping others also with similar problems.
【解决方案2】:

以下内容可以帮助您入门:

示例脚本:

[jaypal:~/Temp] cat s.sh 
#!/bin/bash

echo "Author?"
read author

echo "Title?"
read title

grep -c "$title:$author" file > /dev/null # Look for a line with matching values

if [ $? == 0 ]; then # If found then offer to change price
    echo "I found the book, Do you want to update price to what?"
    read newprice
    sed -i "s/\($book:$author\):[^:]*:/\1:$newprice:/" file
fi

输入数据:

[jaypal:~/Temp] cat file
Hello World:Andreas:10.50:10:5
Lord Of The Rings:Duke:50.15:50:20

执行:

[jaypal:~/Temp] ./s.sh 
Author? 
Andreas
Title? 
Hello World
I found the book, Do you want to update price to what?
40
[jaypal:~/Temp] cat file
Hello World:Andreas:40:10:5
Lord Of The Rings:Duke:50.15:50:20

【讨论】:

  • 感谢您的意见。但是我知道一切是如何工作的,但我不确定这条线实际上是做什么的,因为它的符号非常复杂。 (sed -i "s/($book:$author):[^:]*:/\1:$newprice:/" 文件),需要解释一下吗?干杯。
  • 当然@Andres。 sed 是说 use -i 选项用于对包含 $book:$author 的行进行 infile 编辑。这些变量的值来自用户在运行时提供的值。如果sed 将其归档为一行,则它将该信息(使用括号)和之后的所有其他内容分组,即价格由我们的变量 $newprice 更新。我们使用\1 打印我们在替换部分设置的组,这样我们就不必输入它,它变得更加通用。
  • 这是一个不错的tutorial 供您阅读。 :)
  • 感谢您试图向我解释,但遗憾的是......我真的不明白。我明白这部分 | sed -i "s/($book:$author) | 但我不明白的是这部分 | :[^:]*:/\1:$newprice:
  • 不用担心@Andres。它所说的是匹配冒号和除冒号之外的任何内容。 [^:] 是匹配任何一个字符的字符类。将 ^ 放入其中我们否定了字符类。所以它说找到一个冒号,然后匹配后面不是冒号的任何东西,然后我们在后面加上一个冒号。因此,当 sed 通过它看到的行解析 :price: 时,它所做的是以冒号开头并匹配所有价格,并在看到另一个冒号时停止。
猜你喜欢
  • 2016-06-10
  • 1970-01-01
  • 1970-01-01
  • 2022-08-17
  • 2016-06-29
  • 1970-01-01
  • 2013-03-04
  • 1970-01-01
  • 2020-12-04
相关资源
最近更新 更多